So, I can receive the data and print it but it won't format correctly any more into a list. I have attached all the code below used to get the data and the models. Plus the print outputs. Can someone help me please.
Getting the data
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:world_time/services/model/article_model.dart';
class News {
String? city;
List? articles;
News({this.city});
Future<void> getNews() async {
try {
Response response = await get(Uri.parse('https://newsapi.org/v2/everything?q=$city&from=2021-12-05&sortBy=popularity&apiKey=MY API KEY'));
Map<String, dynamic> json = jsonDecode(response.body);
print(json);
List<dynamic> body = json['articles'];
articles = body.map((dynamic item) => Article.fromJson(item)).toList();
print(articles);
}
catch (e){
print("Caught error: $e");
}
}
}
print(json)
{status: ok, totalResults: 520, articles: [{source: {id: bbc-news, name: BBC News}, author: null, title: Unstoppable Salah closes in on more records - his year in numbers, description: As Liverpool's Mohamed Salah closes in on another record, BBC Sport takes a statistical look at his superb 2021., url: https://www.bbc.co.uk/sport/football/59646200, urlToImage: https://ichef.bbci.co.uk/live-experience/cps/624/cpsprodpb/1269A/production/_122081457_mohamedsalah.jpg, publishedAt: 2021-12-16T08:49:23Z, content: Mohamed Salah has scored 36 goals in all competitions for Liverpool in 2021
I/flutter ( 2307): "He is phenomenal. For sure, at the moment, he is the best player in the world."
I/flutter ( 2307): Liverpool manager Jurgen Klopp may well … [ 5278 chars]}, {source: {id: reuters, name: Reuters}, author: null, title: Man Utd face Villa, Leicester host Watford in FA Cup third round - Reuters, description: Manchester United entertain Aston Villa in the FA Cup third round, while holders Leicester City welcome Watford and West Ham United are at home
print(articles) as articles is null, catch returns this
I/flutter ( 2307): Caught error: type 'Null' is not a subtype of type 'String' in type cast
article_model
class Article {
Source? source;
String? author;
String? title;
String? description;
String? url;
String? urlToImage;
String? publishedAt;
String? content;
Article(
{this.source,
this.author,
this.title,
this.description,
this.url,
this.urlToImage,
this.publishedAt,
this.content});
factory Article.fromJson(Map<String, dynamic> json) {
return Article(
source: Source.fromJson(json['source']),
author: json['author'] as String,
title: json['title'] as String,
description: json['description'] as String,
url: json['url'] as String,
urlToImage: json['urlToImage'] as String,
publishedAt: json['publishedAt'] as String,
content: json['content'] as String,
);
}
}
source_model
String? id;
String? name;
Source({this.id, this.name});
factory Source.fromJson(Map<String, dynamic> json) {
return Source(id: json['id'], name: json['name']);
}
}
CodePudding user response:
on your model, all of your variables are of type String?
that is to say, the variables will be either String
or null
. But when you make the model, you assign all the variables like this: variable: json['variable'] as String
, which means that if they are null
they will throw an error, because you did as String
, not as String?
, that is where the error comes in.
To fix this, I believe it should be possible to completely remove as String
, like this:
factory Article.fromJson(Map<String, dynamic> json) {
return Article(
source: Source.fromJson(json['source']),
author: json['author'],
title: json['title'],
description: json['description'],
url: json['url'],
urlToImage: json['urlToImage'],
publishedAt: json['publishedAt'],
content: json['content'],
);
}
It is possible the above does not work, in case it doesn't the following should:
factory Article.fromJson(Map<String, dynamic> json) {
return Article(
source: Source.fromJson(json['source']),
author: json['author'] as String?,
title: json['title'] as String?,
description: json['description'] as String?,
url: json['url'] as String?,
urlToImage: json['urlToImage'] as String?,
publishedAt: json['publishedAt'] as String?,
content: json['content'] as String?,
);
}