i start yesteraday with flutter and today i have a problem with GET request.
It looks like I can't get data from my URL, I have no idea why when I paste it into my browser everything works
I tried to get one single User object, but nothing work for me :(
my code,
User.dart
class User{
int id;
String firstName;
String lastName;
String email;
User(this.id, this.firstName, this.lastName, this.email);
User.fromJson(Map<String,dynamic> json){
id = json['id'];
firstName = json['firstName'];
lastName = json['lastName'];
email = json['email'];
}
}
my GET function:
Future<User> getCurrentUser() async {
String url = 'http://10.0.2.2:80/user/current';
final response =
await http.get(url, headers: {"Accept": "application/json"});
if (response.statusCode == 200) {
return User.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to load post');
}
}
my widget:
class UserPageState extends State<UserPage>{
Future<List<dynamic>> _user;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Builder(
builder: (context) => Container(
child: FutureBuilder(
future: getCurrentUser(),
builder: (BuildContext context, AsyncSnapshot snapshot){
if(snapshot.hasData ){
return Container(
child: Center(child: Text(snapshot.data['firstName']),),
);
}else {
return Text('NOT LOAD');
}
},
),
),
),
);
}
}
when i paste my url into browser it show me:
{
createdAt: 1584905291338,
updatedAt: 1584905291338,
id: 3,
firstName: "name",
lastName: "surname",
email: "surname#name.com",
admin: false
}
I don't have any more idea what i can do it,
PLEASE HELP ME :(
First of all, I would recommend, that you fetch your data from the initState in the StatefulWidget, and not within the build method. Otherwise, on every rebuild, the data is fetched newly via http.get. In your FutureBuilder widget you use then future: _user
class UserPage extends StatefulWidget {
UserPage({Key key}) : super(key: key);
#override
UserPageState createState() => UserPageState();
}
class UserPageState extends State<UserPage>{
Future<User> _user;
#override
void initState() {
super.initState();
_user = getCurrentUser();
}
#override
Widget build(BuildContext context) {
... // your code here
To answer your question and why the user class and its data isn't filled. You have to return the data from the function User.fromJson(...), otherwise it gets lost
class User{
int id;
String firstName;
String lastName;
String email;
User(this.id, this.firstName, this.lastName, this.email);
factory User.fromJson(Map<String,dynamic> json){
return User(
json['id'],
json['firstName'],
json['lastName'],
json['email'],
);
}
}
class User{
int id;
String firstName;
String lastName;
String email;
// For me, it's better to use named parameter to make it easier to read
User({this.id, this.firstName, this.lastName, this.email});
// this doesn't return User object
User.fromJson(Map<String,dynamic> json){
id = json['id'];
firstName = json['firstName'];
lastName = json['lastName'];
email = json['email'];
}
factory User.fromJson(Map<String,dynamic> json){
return User(
id: json['id'],
firstName : json['firstName '],
lastName : json['lastName '],
email : json['email '],
);
}
}
Related
I'm new to Flutter and I'm trying to create an application with a ListView using this API: https://metmuseum.github.io/#search. Here is my code:
main.dart
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'user.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MET',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<List<User>> usersFuture = getUsers();
static Future<List<User>> getUsers() async {
var body;
for (int i = 0; i < 5; i++) {
String url =
'https://collectionapi.metmuseum.org/public/collection/v1/objects/$i';
var response = await http.get(Uri.parse(url));
body = json.decode(response.body);
}
return body.map<User>(User.fromJson).toList();
}
#override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text("Metropolitan Museum of Art"),
centerTitle: true,
),
body: Center(
child: FutureBuilder<List<User>>(
future: usersFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
} /*else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
final users = snapshot.data!;
return buildUsers(users);
}*/
final users = snapshot.data!;
return buildUsers(users);
},
),
),
);
Widget buildUsers(List<User> users) => ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
final user = users[index];
return Card(
child: ListTile(
leading: CircleAvatar(
radius: 28,
backgroundImage: NetworkImage(user.primaryImageSmall),
),
title: Text(user.title),
subtitle: Text(user.artistDisplayName),
),
);
},
);
}
user.dart
import 'package:flutter/material.dart';
class User {
final int objectID;
final bool isHighlight;
final String accessionYear;
final String primaryImage;
final String primaryImageSmall;
final String department;
final String objectName;
final String title;
final String culture;
final String period;
final String artistPrefix; //da usare prima dell'artista
final String artistDisplayName;
final String artistDisplayBio;
final String medium; //Refers to the materials that were used to create the artwork
final String dimensions;
final String geographyType; //da usare prima della città in cui è stata fatta l'opera
final String city;
final String state;
final String classification;
final String linkResource;
final String GalleryNumber;
const User(
{required this.objectID,
required this.isHighlight,
required this.accessionYear,
required this.primaryImage,
required this.primaryImageSmall,
required this.department,
required this.objectName,
required this.title,
required this.culture,
required this.period,
required this.artistPrefix,
required this.artistDisplayName,
required this.artistDisplayBio,
required this.medium,
required this.dimensions,
required this.geographyType,
required this.city,
required this.state,
required this.classification,
required this.linkResource,
required this.GalleryNumber});
static User fromJson(json) => User(
objectID: json['objectID'],
isHighlight: json['isHighlight'],
accessionYear: json['accessionYear'],
primaryImage: json['primaryImage'],
primaryImageSmall: json['primaryImageSmall'],
department: json['department'],
objectName: json['objectName'],
title: json['title'],
culture: json['culture'],
period: json['period'],
artistPrefix: json['artistPrefix'],
artistDisplayName: json['artistDisplayName'],
artistDisplayBio: json['artistDisplayBio'],
medium: json['medium'],
dimensions: json['dimensions'],
geographyType: json['geographyType'],
city: json['city'],
state: json['state'],
classification: json['classification'],
linkResource: json['linkResource'],
GalleryNumber: json['GalleryNumber']);
}
Now I'm having problems because the ListView is not created and gives me errors. Could you check the code and make sure everything is right?
I think the problem comes from the getUsers() class, where I try to get the API data.
In your user.dart file, you need a fromJson method but
it takes a map<String,dynamic> instead of a json
static User fromJson(Map<String, dynamic> json) => User(
objectID: json['objectID'],
isHighlight: json['isHighlight'],
accessionYear: json['accessionYear'],
primaryImage: json['primaryImage'],
primaryImageSmall: json['primaryImageSmall'],
department: json['department'],
objectName: json['objectName'],
title: json['title'],
culture: json['culture'],
period: json['period'],
artistPrefix: json['artistPrefix'],
artistDisplayName: json['artistDisplayName'],
artistDisplayBio: json['artistDisplayBio'],
medium: json['medium'],
dimensions: json['dimensions'],
geographyType: json['geographyType'],
city: json['city'],
state: json['state'],
classification: json['classification'],
linkResource: json['linkResource'],
GalleryNumber: json['GalleryNumber']);
}
And in your main file
You can create your instance of user like this :
static Future<List<User>> getUsers() async {
var body;
List<User> usersList = [];
for (int i = 1; i < 5; i++) {
String url =
'https://collectionapi.metmuseum.org/public/collection/v1/objects/$i';
var response = await http.get(Uri.parse(url));
body = json.decode(response.body);
usersList.add(User.fromJson(body));
}
return usersList;
}
and finally uncomment your code in the build method
There is a flutter application that I wrote below. I'm trying to connect to mysql database and pull data with api, but every time I try, I get an error like the following. The model codes to which it is linked are also available below.
NoSuchMethodError (NoSuchMethodError: Class '_InternalLinkedHashMap<String, dynamic>' has no instance method 'cast' with matching arguments.
Receiver: _LinkedHashMap len:3
Tried calling: cast<Map<String, dynamic>>()
Found: cast<Y0, Y1>() => Map<Y0, Y1>) I am getting this error. How can I fix.
import 'package:dbconnecttest/data.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Material App',
home: main1(),
);
}
}
class main1 extends StatefulWidget {
main1({Key? key}) : super(key: key);
#override
State<main1> createState() => _main1State();
}
class _main1State extends State<main1> {
Future<List<data>>? futuredata;
#override
void initState() {
// TODO: implement initState
futuredata = fetchPost();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Fake Friends"),
backgroundColor: Colors.green,
),
body: FutureBuilder<List<data>>(
future: futuredata,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (_, index) => Container(
child: Text("${snapshot.data![index].autid}"),
),
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),
);
}
}
Future<List<data>> fetchPost() async {
final response =
await http.get(Uri.parse('http://192.168.1.108/server/data.php'));
if (response.statusCode == 200) {
final parsed = json.decode(response.body).cast<Map<String, dynamic>>();
return parsed.map<data>((json) => data.fromJson(json)).toList();
} else {
throw Exception('Failed');
}
}
import 'dart:convert';
List<data> postFromJson(String str) =>
List<data>.from(json.decode(str).map((x) => data.fromJson(x)));
class data {
int? id;
String? autid;
String? status;
String? startdate;
String? finishdate;
data(
{required this.id,
required this.autid,
required this.status,
required this.startdate,
required this.finishdate});
data.fromJson(Map<String, dynamic> json) {
id = json['id'];
autid = json['autid'];
status = json['status'];
startdate = json['startdate'];
finishdate = json['finishdate'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['autid'] = this.autid;
data['status'] = this.status;
data['startdate'] = this.startdate;
data['finishdate'] = this.finishdate;
return data;
}
}
Try this
Map<String, dynamic>.from(data)
of course i can share. this is my flutter doctor
I am doing my first steps with Flutter and struggling with the JSON parsing.
I have started with the cookbook for fetching data. Everything was fine with my own JSON. Then I switched to the background parsing (as it is more useful), cookbook example worked but as soon as I try to switch to my own JSON I get the following error.
flutter: Exception: NoSuchMethodError:
Class '_InternalLinkedHashMap<String, dynamic>' has no instance method 'cast' with matching arguments.
Receiver: _LinkedHashMap len:6
Tried calling: cast<Map<String, dynamic>>()
Found: cast<Y0, Y1>() => Map<Y0, Y1>
My JSON dart model is generated with the help of quicktype.io and as it is good in the "fetching data" example, I think there is just an issue caused by my JSON format compared to the "background parsing" cookbook example.
I have found similar issues on stackoverflow but the solutions like cast<String, dynamic> did not work. I know the error is within final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>(); but I do not know how I can make it fit my own JSON structure.
Would appreciate any help :)
Coding:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<List<Photo>> fetchPhotos(http.Client client) async {
final response = await client
.get(Uri.parse('https://my-json-url')); //exists of course, just hidden
// Use the compute function to run parsePhotos in a separate isolate.
return compute(parsePhotos, response.body);
}
// A function that converts a response body into a List<Photo>.
List<Photo> parsePhotos(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Photo>((json) => Photo.fromJson(json)).toList();
}
class Photo {
Photo({
required this.errMsg,
required this.errCode,
required this.responseId,
required this.api,
required this.version,
required this.data,
});
final String errMsg;
final String errCode;
final String responseId;
final String api;
final String version;
final PhotoData data;
factory Photo.fromJson(Map<String, dynamic> json) => Photo(
errMsg: json["err_msg"],
errCode: json["err_code"],
responseId: json["response_id"],
api: json["api"],
version: json["version"],
data: PhotoData.fromJson(json["data"]),
);
}
class PhotoData {
PhotoData({
required this.success,
required this.data,
});
final bool success;
final DataData data;
factory PhotoData.fromJson(Map<String, dynamic> json) => PhotoData(
success: json["success"],
data: DataData.fromJson(json["data"]),
);
}
class DataData {
DataData({
required this.results,
required this.total,
});
final List<Result> results;
final int total;
factory DataData.fromJson(Map<String, dynamic> json) => DataData(
results: List<Result>.from(json["results"].map((x) => Result.fromJson(x))),
total: json["total"],
);
}
class Result {
Result({
required this.id,
required this.title,
required this.alias,
required this.introtext,
required this.fulltext,
required this.catid,
required this.state,
required this.created,
required this.modified,
required this.publishUp,
required this.publishDown,
required this.images,
required this.access,
required this.featured,
required this.language,
required this.hits,
required this.createdBy,
required this.tags,
});
final String id;
final String title;
final String alias;
final String introtext;
final String fulltext;
final Catid catid;
final String state;
final DateTime created;
final DateTime modified;
final DateTime publishUp;
final String publishDown;
final Images images;
final String access;
final String featured;
final String language;
final String hits;
final CreatedBy createdBy;
final Tags tags;
factory Result.fromJson(Map<String, dynamic> json) => Result(
id: json["id"],
title: json["title"],
alias: json["alias"],
introtext: json["introtext"],
fulltext: json["fulltext"],
catid: Catid.fromJson(json["catid"]),
state: json["state"],
created: DateTime.parse(json["created"]),
modified: DateTime.parse(json["modified"]),
publishUp: DateTime.parse(json["publish_up"]),
publishDown: json["publish_down"],
images: Images.fromJson(json["images"]),
access: json["access"],
featured: json["featured"],
language: json["language"],
hits: json["hits"],
createdBy: CreatedBy.fromJson(json["created_by"]),
tags: Tags.fromJson(json["tags"]),
);
}
class Catid {
Catid({
required this.catid,
required this.title,
});
final String catid;
final String title;
factory Catid.fromJson(Map<String, dynamic> json) => Catid(
catid: json["catid"],
title: json["title"],
);
}
class CreatedBy {
CreatedBy({
required this.id,
required this.name,
});
final String id;
final String name;
factory CreatedBy.fromJson(Map<String, dynamic> json) => CreatedBy(
id: json["id"],
name: json["name"],
);
}
class Images {
Images({
required this.imageIntro,
required this.floatIntro,
required this.imageIntroAlt,
required this.imageIntroCaption,
required this.imageFulltext,
required this.floatFulltext,
required this.imageFulltextAlt,
required this.imageFulltextCaption,
});
final String imageIntro;
final String floatIntro;
final String imageIntroAlt;
final String imageIntroCaption;
final String imageFulltext;
final String floatFulltext;
final String imageFulltextAlt;
final String imageFulltextCaption;
factory Images.fromJson(Map<String, dynamic> json) => Images(
imageIntro: json["image_intro"],
floatIntro: json["float_intro"],
imageIntroAlt: json["image_intro_alt"],
imageIntroCaption: json["image_intro_caption"],
imageFulltext: json["image_fulltext"],
floatFulltext: json["float_fulltext"],
imageFulltextAlt: json["image_fulltext_alt"],
imageFulltextCaption: json["image_fulltext_caption"],
);
}
class Tags {
Tags({
required this.typeAlias,
required this.itemTags,
});
final dynamic typeAlias;
final List<dynamic> itemTags;
factory Tags.fromJson(Map<String, dynamic> json) => Tags(
typeAlias: json["typeAlias"],
itemTags: List<dynamic>.from(json["itemTags"].map((x) => x)),
);
Map<String, dynamic> toJson() => {
"typeAlias": typeAlias,
"itemTags": List<dynamic>.from(itemTags.map((x) => x)),
};
}
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
const appTitle = 'Isolate Demo';
return const MaterialApp(
title: appTitle,
home: MyHomePage(title: appTitle),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: FutureBuilder<List<Photo>>(
future: fetchPhotos(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) {
print (snapshot.error);
return const Center(
child: Text('An error has occurred!'),
);
} else if (snapshot.hasData) {
return PhotosList(photos: snapshot.data!);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}
}
class PhotosList extends StatelessWidget {
const PhotosList({Key? key, required this.photos}) : super(key: key);
final List<Photo> photos;
#override
Widget build(BuildContext context) {
// just placeholder widgets so far
return ListView.builder(
itemCount: photos.length,
itemBuilder: (context, index) {
return Card(
elevation: 8.0,
child: Column(
children: [
Stack(children: <Widget>[
// Container(
// height: 200.0,
// child: Ink.image(
// image: NetworkImage(photos[index].thumbnailUrl),
// fit: BoxFit.cover,
// ),
// ),
Container(
padding: EdgeInsets.all(16.0),
// alignment workaround
margin: EdgeInsets.only(top: 150.0),
alignment: Alignment.bottomLeft,
child: Text("Text",
style: TextStyle(
//fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.white,
backgroundColor: Colors.orange)),
)
]),
Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.centerLeft,
child: Text("Here we can place some kind of preview text"),
)
],
));
});
//Text();
}
}
Change
jsonDecode(responseBody).cast<Map<String, dynamic>>()
to
jsonDecode(responseBody).cast<String, dynamic>()
to make it not throw.
Then, because that's an unnecessary operation, change it to
jsonDecode(responseBody) as Map<String, dynamic>;
The cast method on collections are used to cast the elements (keys and values for maps). It's not the same as doing an as cast on the collection itself.
Here, the value of jsonDecode is a Map<String, dynamic>, but with static type dynamic. What you want is an as cast to that type.
(Or, if you actually thought the decoded JSON was a List<dynamic> containing Map<String, dynamic> values, then your code is correct, but the incoming JSON source doesn't match your assumption. You'll have to figure out why. Be sure you know the structure of the JSON you decode, the type of the result depends on that.)
Basically im using an API where i can take a numberplate and show information on a vehicle. I managed to get everything working but can't seem to figure out how to display all the information.
Future<Album> fetchAlbum() async {
final response = await http
.get(Uri.parse('https://v1.motorapi.dk/vehicles/CZ33849'),
headers: {"X-AUTH-TOKEN": "rfrzsucnc7eo3m5hcmq6ljdzda1lz793",
"Content-Type": "application/json",
"Accept": "application/json",
});
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return Album.fromJson(jsonDecode(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load album');
}
}
//headers: {"X-AUTH-TOKEN": "rfrzsucnc7eo3m5hcmq6ljdzda1lz793"}
class Album {
final String? registration_number;
final String? status;
final String? type;
final String? use;
final String? first_registration;
final String? vin;
final int? doors;
final String? make;
final String? model;
final String? variant;
final String? model_type;
final String? color;
final String? chasis_type;
final int? engine_power;
final String? fuel_type;
final String? RegistreringssynToldsyn;
final String? date;
final String? result;
Album({
this.registration_number,
this.status,
this.type,
this.use,
this.first_registration,
this.vin,
this.doors,
this.make,
this.model,
this.variant,
this.model_type,
this.color,
this.chasis_type,
this.engine_power,
this.fuel_type,
this.RegistreringssynToldsyn,
this.date,
this.result,
});
factory Album.fromJson(Map<String, dynamic> json) {
return Album(
registration_number: json['registration_number'],
status: json['status'],
type: json['type'],
use: json['use'],
first_registration: json['first_registration'],
vin: json['vin'],
doors: json['doors'],
make: json['make'],
model: json['model'],
variant: json['variant'],
model_type: json['model_type'],
color: json['color'],
chasis_type: json['chasis_type'],
engine_power: json['engine_power'],
fuel_type: json['fuel_type'],
RegistreringssynToldsyn: json['RegistreringssynToldsyn'],
date: json['date'],
result: json['result'],
);
}
}
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late Future<Album> futureAlbum;
#override
void initState() {
super.initState();
futureAlbum = fetchAlbum();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: const Text('Fetch Data Example'),
),
body: Center(
child: FutureBuilder<Album>(
future: futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text("${snapshot.data!.use}");
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
// By default, show a loading spinner.
return const CircularProgressIndicator();
},
),
),
),
);
}
}
When i edit this line: return Text("${snapshot.data!.use}");, i can replace use with other variables from Album class, but i can't seem to figure out how to display it all at once.
How you want to display? It is depend on your UI. If you want to put it all in a single Text widget, you can do like that
class User {
String name;
String address;
toString() {
return "name: " + name + ", address: " + address;
}
}
Or You can use Column/Row Widget to show per Text Widget.
I am trying o get data from newsApi but i seem to be getting the error above.
included is my main.dart code
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<List<Article>> fetchArticles(http.Client client) async {
//final response = await client.get(Uri.parse('https://jsonplaceholder.typicode.com/Articles'));
String link = "https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=MykEYhere";
final response = await client.get(Uri.parse(link));
// Use the compute function to run parseArticles in a separate isolate.
return compute(parseArticles, response.body);
}
// A function that converts a response body into a List<Article>.
List<Article> parseArticles(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Article>((json) => Article.fromJson(json)).toList();
}
class Article {
final String author;
final String title;
final String description;
final String url;
final String urlToImage;
final String content;
const Article({
required this.author,
required this.title,
required this.description,
required this.url,
required this.urlToImage,
required this.content
});
factory Article.fromJson(Map<String, dynamic> json) {
return Article(
author: json['author'],
title: json['title'],
description: json['description'],
url: json['url'],
urlToImage: json['urlToImage'],
content: json['content'],
);
}
}
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
const appTitle = 'NewApi Trial';
return const MaterialApp(
title: appTitle,
home: MyHomePage(title: appTitle),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: FutureBuilder<List<Article>>(
future: fetchArticles(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Center(
child: Text('An error has occurred! ${snapshot.error}'),
);
} else if (snapshot.hasData) {
return ArticlesList(articles: snapshot.data!);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}
}
class ArticlesList extends StatelessWidget {
const ArticlesList({Key? key, required this.articles}) : super(key: key);
final List<Article> articles;
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: articles.length,
itemBuilder: (context, index) {
return ClipRect(
child: Column(
children: [
Image.network(articles[index].urlToImage),
Text(articles[index].title)
],
),
);
//Image.network(Articles[index].thumbnailUrl);
},
);
}
}
below is the Error im getting after running the code
NoSuchMethodError: Class'_InternalLinkedHashMap<String, dynamic>'has no instance method 'cast' with matching arguments. Reciever: _LinkedHashMap len:3 tried calling: cast<Map<String, dynamic>>() Founf: cast<RK, RV>()=>Map<RK, RV>
your assistance will be greatly appreciated
main.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'news_model.dart';
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
));
}
// ignore: use_key_in_widget_constructors
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
NewsModel? newsmodel;
List<Articles>? articles;
Future<List<Articles>?> fetchNews() async {
final response = await http.get(Uri.parse(
"https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=YourAPIKEYHere"));
if (response.statusCode == 200) {
newsmodel = NewsModel.fromJson(jsonDecode(response.body));
setState(() {
articles = newsmodel!.articles;
});
return articles;
} else {
articles = null;
}
}
#override
void initState() {
fetchNews();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<List<Articles>?>(
future: fetchNews(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Center(
child: Text('An error has occurred! ${snapshot.error}'),
);
} else if (snapshot.hasData) {
return ArticlesList(articles: articles);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}
}
class ArticlesList extends StatelessWidget {
const ArticlesList({Key? key, this.articles}) : super(key: key);
final List<Articles>? articles;
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: articles!.length,
itemBuilder: (context, index) {
return ClipRect(
child: Column(
children: [
Image.network(articles![index].urlToImage.toString()),
Text(articles![index].title.toString())
],
),
);
//Image.network(Articles[index].thumbnailUrl);
},
);
}
}
news_model.dart
class NewsModel {
String? status;
int? totalResults;
List<Articles>? articles;
NewsModel({this.status,this.totalResults,this.articles});
NewsModel.fromJson(Map<String, dynamic> json) {
status = json['status'];
totalResults = json['totalResults'];
if (json['articles'] != null) {
articles = <Articles>[];
json['articles'].forEach((v) {
articles!.add(Articles.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['status'] = status;
data['totalResults'] = totalResults;
if (articles != null) {
data['articles'] = articles!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Articles {
Source? source;
String? author;
String? title;
String? description;
String? url;
String? urlToImage;
String? publishedAt;
String? content;
Articles(
{this.source,
this.author,
this.title,
this.description,
this.url,
this.urlToImage,
this.publishedAt,
this.content});
Articles.fromJson(Map<String, dynamic> json) {
source =
json['source'] != null ? Source.fromJson(json['source']) : null;
author = json['author'] ?? "Anonymous";
title = json['title'] ?? "Information Not Available";
description = json['description'] ?? "Description Not Available";
url = json['url'] ?? "https://i.imgur.com/8UdKNS4.jpg";
urlToImage = json['urlToImage'] ?? "https://i.imgur.com/8UdKNS4.jpg";
publishedAt = json['publishedAt'] ?? "Date Unavailable";
content = json['content'] ?? "Content Unavailable";
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
if (source != null) {
data['source'] = source!.toJson();
}
data['author'] = author;
data['title'] = title;
data['description'] = description;
data['url'] = url;
data['urlToImage'] = urlToImage;
data['publishedAt'] = publishedAt;
data['content'] = content;
return data;
}
}
class Source {
String? id;
String? name;
Source({this.id, this.name});
Source.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{} ;
data['id'] = id;
data['name'] = name;
return data;
}
}
Find the complete project here