Вот мой код, который должен возвращать JSON. Я адаптировал этот код здесь https://github.com/flutter/flutter/issues/15110

  Stream _defaultReturn(HttpClientResponse httpClientResponse) {
    Stream response = httpClientResponse.
                      transform(utf8.decoder).
                      transform(json.decoder).
                      asyncMap((json) => jsonDecode(json));
    return response;
  }

  Future<dynamic> get(String endpoint) async {
    HttpClientRequest httpClientRequest =
        await httpClient.getUrl(Uri.parse(_url + endpoint));
    _addCookies(httpClientRequest);
    final HttpClientResponse httpClientResponse =
        await httpClientRequest.close();
    return _defaultReturn(httpClientResponse);
  }

Я поместил тип возврата Stream в _defaultReturn, потому что intellisense сказал мне, что гигантская вещь вернула мне Stream. Я на самом деле хотел бы получить JSON (который должен быть карта). Я думаю, что я использую или подписываюсь на этот поток, чтобы получить что-то полезное. Тем не менее, я не вижу парсин JSON в качестве потока, как быть полезным. Разве мне не нужен весь JSON перед анализом? Разве я не должен просто накапливать все в String, а затем просто вызывать jsonDecode?

Какой самый эффективный способ вернуть JSON из HTTP-вызова? И как это сделать?

5
Guerlando OCs 14 Фев 2020 в 08:46

2 ответа

Лучший ответ

json.decoder будет прослушивать исходный поток и всегда преобразовывать его содержимое в всего один Object, поэтому вы можете просто вернуть его с .first потока :

Future<Object> get(String endpoint) async {
  var httpClientRequest = await httpClient.getUrl(Uri.parse(_url + endpoint));
  _addCookies(httpClientRequest);
  final httpClientResponse = await httpClientRequest.close();
  return httpClientResponse
           .transform(utf8.decoder)
           .transform(json.decoder)
           .first;
}

Тогда вы можете использовать это так:

var jsonObject = await myHttpClient.get(myEndpoint);
3
Styx 22 Фев 2020 в 10:27

Существует пакет с именем JSON_Serializable, который вы можете использовать. Создайте свой объектный класс, и вы сможете отобразить свой HTTP-возврат в класс.

final response = await http.get(url, headers: await setHeaders());
dynamic parsed = jsonDecode(await response.body);
YourItemsList = List<YourItems>.from(
    parsed['data'].map((i) => YourItems.fromJson(i)));

Ваше поколение класса будет включать обе функции ниже:

  factory YourItemsList.fromJson(Map<dynamic, dynamic> json) =>
  _$YourItemsListFromJson(json);

  Map<String, dynamic> toJson() => _$YourItemsListToJson(this);
2
xion 14 Фев 2020 в 06:01