【问题标题】:does not return response in API call, with http package在 API 调用中不返回响应,带有 http 包
【发布时间】:2021-02-23 01:21:40
【问题描述】:

我正在使用flutter的Http包连接API,但我看到它没有返回任何内容,也没有捕获错误。

这是代码。

只打印第一个print()

   Future getCountryByName(String name) async {
    try {
      print(name);

      final url = 'https://restcountries.eu/rest/v2/name/colombia';
      final response = await http.get(url);
      print(response);
      return [];
    } catch (e) {
      print(e);
    }
  }

【问题讨论】:

  • 它不返回任何东西,因为你返回 [ ],而且你必须定义你未来的类型

标签: flutter dart flutter-layout flutter-dependencies flutter-test


【解决方案1】:

网络服务:

class NetService {
  static Future<T> getJson<T>(String url) {
    return http.get(Uri.parse(url))
      .then((response) {
        if (response.statusCode == 200) {
          return jsonDecode(response.body) as T;
        }
        print('Status Code : ${response.statusCode}...');
        return null;
      })
      .catchError((err) => print(err));
  }
}

主要:

import 'package:_samples2/networking.dart';

class Country {
  static const url = 'https://restcountries.eu/rest/v2/name/colombia';

  static Future<List> getColombiaInfo() async {
    print('Start fetching...');
    return await NetService.getJson<List>(url).whenComplete(() => print('Fetching done!'));
  }
}

void main(List<String> args) async {
  var info = await Country.getColombiaInfo();

  print(info);
}

结果:

Start fetching...
Fetching done!
[{name: Colombia, topLevelDomain: [.co], alpha2Code: CO, alpha3Code: COL, callingCodes: [57], capital: Bogotá, altSpellings: [CO, Republic of Colombia, República de Colombia], region: Americas, subregion: South America, population: 48759958, latlng: [4.0, -72.0], demonym: Colombian, area: 1141748.0, gini: 55.9, timezones: [UTC-05:00], borders: [BRA, ECU, PAN, PER, VEN], nativeName: Colombia, numericCode: 170, currencies: [{code: COP, name: Colombian peso, symbol: $}], languages: [{iso639_1: es, iso639_2: spa, name: Spanish, nativeName: Español}], translations: {de: Kolumbien, es: Colombia, fr: Colombie, ja: コロンビア, it: Colombia, br: Colômbia, pt: Colômbia, nl: Colombia, hr: Kolumbija, fa: کلمبیا}, flag: https://restcountries.eu/data/col.svg, regionalBlocs: [{acronym: PA, name: Pacific Alliance, otherAcronyms: [], otherNames: [Alianza del Pacífico]}, {acronym: USAN, name: Union of South American Nations, otherAcronyms: [UNASUR, UNASUL, UZAN], otherNames: [Unión de Naciones Suramericanas, União de Nações Sul-Americanas, Unie van Zuid-Amerikaanse Naties, South American Union]}], cioc: COL}]

【讨论】:

    【解决方案2】:

    1/ 您必须为您的 Future 定义类型(在 之间),一个表示延迟计算的对象,才能正常工作

    Future 用于表示将来某个时间可用的潜在值或错误。 Future 的接收者可以注册回调来处理可用的值或错误。例如:

    2/还请仔细阅读documentation for http

    http.get() 方法返回一个包含响应的 Future

    3/ 也请阅读documentation for FutureBuilder,因为您可能会需要它。

    完整的工作示例

    您可以按照文档的示例正确获取您的数据:

    class Country {
      final String name;
      final String capital;
      final String region;
    
      Country({this.name, this.capital, this.region});
    
      factory Country.fromJson(Map<String, dynamic> json) {
        return Country(
          name: json['name'],
          capital: json['capital'],
          region: json['region'],
        );
      }
    
      @override
      String toString() { // nice override to quickly get info about your json
        return 'Country{name: $name, capital: $capital, region: $region)';
      }
    }
    
    Future<Country> getCountryByName  (String name) async {
      Country country;
      try {
        final url = 'https://restcountries.eu/rest/v2/name/$name';
        final response = await http.get(url);
        if (response.statusCode == 200) {
          print(response.body);
    
          country = Country.fromJson(json.decode(response.body)[0]); // the response that you get is an array, you just want to first item.
        }
        else
          print("error: ${response.statusCode}");
      }
      catch (e) {
        print(e);
      }
        print(country.toString());
        return country;
    }
    
    

    您的有状态小部件应如下所示:

    class MyHomePage extends StatefulWidget {
    MyHomePage({Key key, this.title}) : super(key: key);
    
    final String title;
    
    @override
    _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child:  FutureBuilder<Country>(
            future: getCountryByName("colombia"),
            builder: (context, AsyncSnapshot<Country> snapshot) {
              if (snapshot.connectionState == ConnectionState.done &&
                  snapshot.hasData) {
                return Text(snapshot.data.toString());
              }
              else
                return CircularProgressIndicator();
        })
    
          ),
        );
      }
    }
    

    当然不要忘记导入:

    import 'package:flutter/material.dart';
    import 'dart:convert'; // for json.decode
    import 'package:http/http.dart' as http; // for get request
    

    我在Github上传了这个项目,如果你想试试的话。

    【讨论】:

      【解决方案3】:

      更正的代码:

      import 'dart:convert' as convert; // for jsonDecode
      import 'package:http/http.dart' as http;
      
       Future getCountryByName(String name) async {
        try {
          print(name);
      
          final url = 'https://restcountries.eu/rest/v2/name/colombia';
          // http.get returns future of type Future<Response>
          final response = await http.get(url);
          // parse the response and get the resulting json reponse
          var jsonResponse = convert.jsonDecode(response.body);
          print(jsonResponse);
          return [];
        } catch (e) {
          print(e);
        }
      }
      

      参考:http package usage guide

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-01
        • 1970-01-01
        • 2014-04-30
        • 1970-01-01
        • 1970-01-01
        • 2018-04-14
        • 2017-01-11
        • 1970-01-01
        相关资源
        最近更新 更多