#dart #bloc #flutter-bloc
Вопрос:
Я возвращаю объект json из запроса post и хочу проанализировать его в модели dart. Я уже сгенерировал модель и fromJson
функцию dart.
factory Did.fromJson(Map<String, dynamic> json) => Did(
id: json['id'] as String,
docHash: json['docHash'] as String,
pubKey: json['pubKey'] as String,
privKey: json['privKey'] as String,
credential:
Credential.fromJson(json['credential'] as Map<String, dynamic>),
message: json['message'] as String,
success: json['success'] as bool);
Это всего лишь выдержка из моей модели, но та часть, в которой я получил ошибку The argument type 'dynamic' can't be assigned to the parameter type 'Map<String, dynamic>'
. Я пытаюсь проанализировать ответ на объект dart после создания запроса post в репозитории блоков:
var res = await dio.post("http://did-backend.herokuapp.com/create",
data: {
"firstName": firstName.trim(),
"lastName": lastName.trim(),
"email": email.trim(),
"phoneNumber": phoneNumber.trim(),
"dateOfBirth": dateOfBirth?.toIso8601String(),
"sex": sex.trim(),
"address": address.trim(),
"city": city.trim(),
"state": state.trim(),
"postalCode": postalCode.trim(),
"country": country.trim()
},
options: Options(headers: {
Headers.contentTypeHeader: "application/json",
}));
if (res.statusCode == 200) {
final json = jsonDecode(res.data.toString());
print(Did.fromJson(json));
return Did.fromJson(json);
}
Декодированный объект json имеет тип dynamic, поэтому я не могу передать его в Did.fromJson()
функцию.
Как я должен преобразовать ответ Dio, чтобы передать его в fromJson
функцию?
Редактировать:
Это моя модель, которая включает в себя функцию FromJSON Did.dart
Правка 2:
Ответ на запрос Dio post, который еще не проанализирован:
print(res)
{
"id": "GbLnu9eCQ2sVBiKngNxts6NJMprxRczc63CKaZsiJsGT",
"docHash": "PNSGTXSGODDBHRVWUTFIZUJT9UMPNM9MFBEMCQBYSIRQTDKXPVUCSPNBCXVNGIFEMWSBRUBYARZDA9999",
"pubKey": "38aqV9FLAn9bXSPm388LcTronqZabEzpWKQpBZRcpPwP",
"privKey": "A7cq3Z3eCN573wL4QDPR2UjwnDMML6deTf499RnN64zE",
"credential": {
"@context": "https://www.w3.org/2018/credentials/v1",
"id": "http://example.edu/credentials/3732",
"type": ["VerifiableCredential", "personalInformationCredential"],
"credentialSubject": {
"id": "did:iota:GbLnu9eCQ2sVBiKngNxts6NJMprxRczc63CKaZsiJsGT",
"address": {
"street": "awdwada",
"city": "wdwad",
"state": "awdad",
"postalCode": "awdwad",
"country": "wadawd"
},
"dateOfBirth": "2021-04-24T00:00:00.000",
"email": "awdadawd@adwad.co",
"name": { "first": "wadawd", "last": "awdawd" },
"phoneNumber": "awdad",
"sex": "male"
},
"issuer": "did:iota:A5STNhet1zgGbbnZCqniokcAdXbZZ2xcE6QWruQmctEs",
"issuanceDate": "2021-04-24T15:02:41Z",
"proof": {
"type": "MerkleKeySignature2021",
"verificationMethod": "#key-collection",
"signatureValue": "3RypuceLDTQt1Anb9WdBj7ayPS91EdiYJ6ELPMChgocm.1117tuDcgbUJddXaLoFqvAh8WWeypGnCTuPCDggJ2cMk6AVyJAjHaaCgSmgaKsGa299TxVBqfypgqbjQx1gExf2kkD9XU8ViYhZRVm9dx5qELnVxcM2H5R5YmL6rLn3RR6SbiNSc7XG.22rTApWSHuzuZNFtN75KcsEVqhgzDG3WGoAxs2itVdy99DkKRSVkbCyhJgd1pgAQPPpnt65Sh3m733PsnY6QFojF"
}
},
"message": "You have successfully created your digital identity, wadawd",
"success": true
}
Ответ №1:
Если вы уверены в типе, вам просто нужно указать его явно, введя as
ключевое слово (https://dart.dev/guides/language/language-tour#type-test-operators).
Например:
final json = jsonDecode(res.data.toString()) as Map<String, dynamic>;
print(Did.fromJson(json));
Комментарии:
1. Теперь я получаю ошибку:
type 'List<dynamic>' is not a subtype of type 'List<String>' in type cast
так что моя функция синтаксического анализа, вероятно, неверна.2. Не могли бы вы предоставить образец, высмеянный
res
для целей тестирования? С помощью предоставленной вами модели, возможно, я смогу воспроизвести проблему3. Я добавил ответ Dio на свой вопрос внизу. Я напечатал не проанализированный ответ. Я уже могу получить доступ к проанализированному ответу от Dio с помощью res.data.
4. @JonasLevin круто, остающаяся проблема, похоже, связана с
type
учетными данными.FromJSON: вместоtype: json['type'] as List<String>
этого вам придется сделать что-то вродеtype: json['type'] is List ? (json['type'] as List).map((e) => e as String).toList() : [],
(код можно улучшить, но он должен дать представление)5. Я больше не получаю ошибок после вашей реализации. Я буду продолжать работать с ним и реализовывать локальное сохранение данных. Спасибо за ваши ответы.
Ответ №2:
Попробуй изменить себя fromJson
, чтобы быть таким:
id = json['id'];
docHash = json['docHash'];
pubKey = json['pubKey'];
privKey = json['privKey'];
credential = json['credential'] != null
? new Credential.fromJson(json['credential'])
: null;
message = json['message'];
success = json['success'];
Редактировать:
Я пытаюсь сделать запрос к вашему Api, я сгенерировал модель для вас, используйте ее вместо вашей
ссылка для скачивания: Модель данных
Комментарии:
1. Я использовал этот пакет для создания своей модели, в нем уже реализована нулевая безопасность. Но модальный также довольно большой, 423 строки, поэтому я не хотел вставлять его в свой вопрос. Это моя модель
Ответ №3:
Обратите внимание на res.data
тип — Dio уже расшифровал его в json, и вы можете передавать данные непосредственно в конструктор:
if (res.statusCode == 200) {
print(res.data.runtimeType); // _InternalLinkedHashMap<String, dynamic>
return Did.fromJson(res.data);
}
К вашему сведению, вы можете изменить тип данных ответа, используя свойство responseType, например:
var res = await dio.post('http://did-backend.herokuapp.com/create',
data: {
// ...
},
options: Options(
responseType: ResponseType.plain,
headers: {
// ...
},
));