颤抖地从API获取数据

时间:2020-10-20 17:29:29

标签: json api flutter dart flutter-futurebuilder

正在尝试使用API​​来获取数据

我的代码

class _MyAppState extends State<MyApp> {
  Future<News> news;

  @override
  void initState() {
    super.initState();
    news = fetchNews();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: 
      Container(
        color: Colors.white24,
        child:
        Center(child:
        FutureBuilder<News>(
  future: fetchNews(),
  builder: (context, snapshot) {
    if (snapshot.hasData) {

        /* here if I removed toString() it gives me error
         The argument type 'News' can't be assigned to the parameter type 
         'String'. */ 

       return Text(snapshot.data.toString());
    } else if (snapshot.hasError) {
      return Text("${snapshot.error}");
    }

    // By default, show a loading spinner.
    return CircularProgressIndicator();
            },
           ),
          ),
         )
        );
       }
      }
News newsFromJson(String str) => News.fromJson(json.decode(str));

String newsToJson(News data) => json.encode(data.toJson());

class News {
    News({
        this.status,
        this.totalResults,
        this.articles,
    });

    String status;
    int totalResults;
    List<Article> articles;

    factory News.fromJson(Map<String, dynamic> json) => News(
        status: json["status"],
        totalResults: json["totalResults"],
        articles: List<Article>.from(json["articles"].map((x) => Article.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "status": status,
        "totalResults": totalResults,
        "articles": List<dynamic>.from(articles.map((x) => x.toJson())),
    };
}

class Article {
    Article({
        this.source,
        this.author,
        this.title,
        this.description,
        this.url,
        this.urlToImage,
        this.publishedAt,
        this.content,
    });

    Source source;
    String author;
    String title;
    String description;
    String url;
    String urlToImage;
    DateTime publishedAt;
    String content;

    factory Article.fromJson(Map<String, dynamic> json) => Article(
        source: Source.fromJson(json["source"]),
        author: json["author"] == null ? null : json["author"],
        title: json["title"],
        description: json["description"] == null ? null : json["description"],
        url: json["url"],
        urlToImage: json["urlToImage"] == null ? null : json["urlToImage"],
        publishedAt: DateTime.parse(json["publishedAt"]),
        content: json["content"],
    );

    Map<String, dynamic> toJson() => {
        "source": source.toJson(),
        "author": author == null ? null : author,
        "title": title,
        "description": description == null ? null : description,
        "url": url,
        "urlToImage": urlToImage == null ? null : urlToImage,
        "publishedAt": publishedAt.toIso8601String(),
        "content": content,
    };
}

class Source {
    Source({
        this.id,
        this.name,
    });

    dynamic id;
    String name;

    factory Source.fromJson(Map<String, dynamic> json) => Source(
        id: json["id"],
        name: json["name"],
    );

    Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
    };
}

Future<News> fetchNews() async {
  final response = await http.get('My-Api');

  if (response.statusCode == 200) {
    
    return News.fromJson(jsonDecode(response.body));
  } else {
    
    throw Exception('Failed to load album');
  }
}

当我运行此代码时,输​​出为: “新闻”实例

我搜索了互联网,发现大多数解决方案都说我必须增加等待时间。

唯一的问题是他们不说我应该在代码中准确地输入

我们将为您提供帮助

谢谢

注意:我仍然是初学者

1 个答案:

答案 0 :(得分:0)

您不需要添加await。您的代码正常工作。我唯一要改变的是

FutureBuilder<News>(
   future: fetchNews(),

FutureBuilder<News>(
   future: news,

Here是对此的很好解释。

您的输出Instance of 'News'是正确的。这是您为网络通话的输出声明的model。现在,您可以访问它的属性(statustotalResultsarticles)。

/ *在这里,如果我删除了toString(),则会给我错误 无法将参数类型“新闻”分配给参数类型 '串'。 * /

这是因为Text小部件期望他的输入是类型String而不是类型News