Flutter - Http get json data - json

My http-get json data in flutter project it can't get the data, I've tested with postman and it's succeed, but in flutter it's didn't or because of me don't know how to put in. I've try different ways but none are succeed!
Can anyone help me?! If anyone need more info, I'll give it to you!
Flutter Debug Console: https://i.stack.imgur.com/IGZDP.png
Postman tested succeed: https://i.stack.imgur.com/khj9a.png
Postman tested failed: https://i.stack.imgur.com/Ee6tU.png
Future<Get> getdata(String id) async {
final username = 'test';
final password = '9876543';
final credentials = '$username:$password';
final stringToBase64 = utf8.fuse(base64);
final encodedCredentials = stringToBase64.encode(credentials);
final String apiUrl = "http://sv.com/api/values/";
Map<String, String> headers = {
HttpHeaders.contentTypeHeader: "application/json; charset=utf-8",
HttpHeaders.authorizationHeader: "Basic $encodedCredentials",
};
final response = await http.get(apiUrl,headers: headers);
if (response.statusCode == 200) {
final String responseString = response.body;
print(response.statusCode);
print(responseString);
return Get.fromJson(json.decode(response.body));
} else {
print(response.statusCode);
print(response.body);
}
}
Get class
class Get {
final String id;
Get({
this.id,
});
factory Get.fromJson(Map<String, dynamic> json) {
return Get(
id: json['id_machdien'].toString()
);
}
}
Main
class _MyHomePageState extends State<MyHomePage> {
Get _dataget;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body:Center(
child: Column(
children: <Widget> [
RaisedButton(
onPressed: () async{
final Get dataget = await getdata(id);
setState(() {
_dataget = dataget;
});
},
child: Text('Mở',style: TextStyle(fontSize: 15)),
),
],
),
),
)
);
}
}

Let me correct you,
You can't send body with GET http request, so change the API to POST or send id_machdien as Query parameter.
Inside class Get You are trying to parse json['id_machdien'] but in your response there is no id_machdien, it must be one of the response's item (like : id, trang_thai_app).

Related

Mysql query result in Flutter Widgets

Trying to display in Flutter a result I am receiving from my Node.JS server via MySQL query:
[{"NAME":"Matematicas"},
{"NAME":"Naturales"},
{"NAME":"Ciencias Sociales"},
{"NAME":"Lenguaje"},
{"NAME":"Religion"}]
This is the class I am using in Flutter to handle it:
class Subject {
final String name;
Subject({
required this.name,
});
factory Subject.fromJson(Map<String, dynamic> json) {
return Subject(name: json['NAME']);
}
}
This is the method from which I obtain the data:
Future<Subject> fetchSubject() async {
var prefs = await SharedPreferences.getInstance();
var token = prefs.getString('token');
var response = await http.get(Uri.parse('http://localhost:8000/subjects'),
headers: {'x-access-token': token!});
print(response.body);
return Subject.fromJson(jsonDecode(response.body));
}
This is my initState
void initState() {
super.initState();
futureSubject = fetchSubject();
}
This is my Widget build piece:
Widget build(BuildContext context) {
return FutureBuilder<Subject>(
future: fetchSubject(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Center(
child: Text('Error'),
);
} else if (snapshot.hasData) {
return Scaffold(
appBar: AppBar(
title: Text('Materias'),
backgroundColor: Colors.green[300],
actions: [
Padding(
padding: EdgeInsets.only(right: 3.0),
child: IconButton(
icon: Icon(Icons.logout),
//TODO llamar funcion logout
onPressed: () {},
iconSize: 26,
),
)
],
),
body: Text(snapshot.data!.name));
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
});
}
This is what I get:
Uncaught (in promise) Error: Expected a value of type 'Map<String, dynamic>', but got one of type 'List<dynamic>'
I just want to display the information I am receiving as a List or table like fashion. Any ideas on what and how to refactor this?
Its happened because your return data is an array. Try this
final data = json.decode(response.body);
return List<Subject>.from(data.map((value) => Subject.fromJson(value)));
It looks like the fetchSubject method needs to be modified and the widget itself. The data you displayed is a List of objects, thus the error that you are trying to see type Map<String, dynamic> from jsonDecode(response.body) but it returns a List<dynamic> instead. Thus, you need to modify fetchSubject and get a List<Subject from your API not just an object. Or, you need to update an API. Just as an example (haven't tested it but should work):
Future<List<Subject>> fetchSubject() async {
var prefs = await SharedPreferences.getInstance();
var token = prefs.getString('token');
var response = await http.get(Uri.parse('http://localhost:8000/subjects'),
headers: {'x-access-token': token!});
print(response.body);
return jsonDecode(response.body).map((item) => Subject.fromJson(item));
}
and change all logic to handle a List of Subject and not just Subject. The JSON your API returns is a list (array) of objects, not just an object.

How to fetch and show data from a json file which has a list of nested maps

I'm trying to fetch and show data from the json file which contains a list of nested maps, as a beginner I'm facing lot of difficulties while coding it, please help me to fetch and show data from the json file. I don't know how to fetch data, I have to show the name, email, city, age etc in the App UI. I don't know what is the procedure to work this nested maps. Help me to make this code work.
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:http/http.dart';
import 'package:task/model/model_class.dart';
class EmployeeListView extends StatefulWidget {
#override
_EmployeeListViewState createState() => _EmployeeListViewState();
}
class _EmployeeListViewState extends State<EmployeeListView> {
List<Results> _results = List<Results>();
#override
void initState() {
super.initState();
fetchResults.then((value){
setState(() {
_results.addAll(value);
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Employee"),
backgroundColor: Colors.black,
),
body: ListView.builder(
itemCount: 10,
itemBuilder: (context, index){
return Card(
color: Colors.white,
shadowColor: Colors.black,
elevation: 4.5,
child: ListTile(
leading: CircleAvatar(
backgroundColor: Colors.transparent,
radius: 25.0,
backgroundImage: NetworkImage("url"),
),
title: Text("Name"),
subtitle: Text("Email"),
trailing: IconButton(icon: Icon(Icons.call), onPressed: (){}),
),
);
}),
);
}
Future<List<Results>> fetchResults() async{
var url = "https://randomuser.me/api?page=2&results=10&seed=99d7541361f1e116";
var response = await http.get(url);
if(response.statusCode == 200){
var resultsJson = json.decode(response.body);
for(var resultsJson in resultsJson){
_results.add(Results.fromJson(resultsJson));
return _results;
}
}
}
}
I can see you made a mistake somewhere in your for loop.
for(var resultsJson in resultsJson){
_results.add(Results.fromJson(resultsJson));
return _results;
You used the JsonList(resultsJson) to represent a Json object in the list.
Declare a new list too, and return outside the loop. Change this to;
List<Results> resultsList = [];
for(var result in resultsJson){
resultsList.add(Results.fromJson(result));
}
return resultsList;
Try that out and give feedback please.
Okay according to your code in init state. i don't recommend that you use setState in initState but rather inside didChangeDependences.
You have to decode the json data from the http request
From response its returning the [result] and [info]
I have use the result section and provided the details
Step 1:
class Results {
String gender;
String phone;
String nat;
DocumentReference reference;
Results(this.gender, this.phone, this.nat);
factory Results.fromSnapshot(DocumentSnapshot snapshot) {
Results newEmployee = Results.fromJson(snapshot.data());
newEmployee.reference = snapshot.reference;
return newEmployee;
}
factory Results.fromJson(Map<String, dynamic> json) =>
_resultsFromJson(json);
Map<String, dynamic> toJson() => _resultsToJson(this);
#override
String toString() => 'employeeName ${Results}';
}
Results _resultsFromJson(Map<String, dynamic> data) {
return Results(
data['gender'],
data['phone'],
data['nat'],
);
}
Map<String, dynamic> _resultsToJson(Results instance) {
return {
'gender': instance.gender,
'phone': instance.phone,
'nat': instance.nat,
};
}
Step 2:
List<Results> collectionData = [];
#override
void initState() {
super.initState();
fetchResults().then((value) {
setState(() {
collectionData.addAll(value);
});
});
}
Future<List<Results>> fetchResults() async {
List<Results> _results = [];
var url =
"https://randomuser.me/api?page=2&results=10&seed=99d7541361f1e116";
var response = await http.get(url);
if (response.statusCode == 200) {
var resultsJson = json.decode(response.body)['results'].cast<Map<String,dynamic>>();
await Future.forEach(resultsJson, (element) {
_results.add(Results.fromJson(element));
});
}
return Future.value(_results);
}

Flutter - Errors when trying to save JSON Array to List

I am new to flutter and trying to fetch API data into a list. My goal is to later input that information into a ListView.
I am familiar with doing api calls but now I'm triying to get information from a json array. Previously I made a model class to retrieve the objects I need to continue with my process, but I've reached a dead end since I can't seem to figure out how to extract the objects from an array properly.
I am using multiple files. "API Services", "readData Model", and the actual screen where the data will be shown.
Everything else is fine, it's just that I am unable to actually save the data to a list.
First I will show you how my code is set up and the JSON response data I am trying to save:
JSON Response Body:
The example I am showing only has one chunk of image data, but we need an array for it since it should be displaying every chunk in a list.
{"status":200,
"content":[{"image_id":"151",
"image_url":"https:\\\/imageurl.jpg",
"returned_value":"14.0",
"alarm":"false",
"account":"test#email.com",
"create_at":"2020-11-17 07:13:42",
"location":"NY"
}]
}
API POST function:
Future<ReadResponseModel> readData(
ReadRequestModel requestData) async {
final response = await http.post("$url/read",
body: requestData.toJson() ,
headers: {
"Client-Service": "frontend-client",
"Auth-Key": "simplerestapi",
"Content-Type":"application/x-www-form-urlencoded",
"Authorization": token,
"User-ID": userId,
});
print(response.body);
if (response.statusCode == 200 || response.statusCode == 400) {
dynamic resBody = json.decode(response.body);
return ReadResponseModel.fromJson(resBody);
} else {
throw Exception('Failed to load data!');
}
}
readResponseModel Class:
I have tried two methods to process this information but have failed at both of them.
This is Method 1:
This one will give me the following error: [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'
Originally set as final String for all values, but since I was getting this error I've been trying to make sure each one is the correct type (ex. retVal as int or alarm as bool). Still no luck so far.
class ReadResponseModel {
final dynamic imageID;
final dynamic imgUrl;
final dynamic retVal;
final bool alarm;
final dynamic account;
final dynamic createAt;
final dynamic location;
ReadResponseModel({this.imageID, this.imgUrl, this.retVal, this.alarm,
this.account, this.createAt, this.location,});
factory ReadResponseModel.fromJson(Map<String , dynamic> json) {
return ReadResponseModel(
imageID: json['content']['image_id'] as String ,
imgUrl: json['content']['image_url'] as String ,
retVal: json['content']["returned_value"] as String,
alarm: json['content']['alarm'] as bool ,
account: json['content']['account'] as String,
createAt: json['content']['create_at'] as String,
location: json['content']['location'] as String,
);
}
}
Method 2:
This one will give me the following error:
[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: type '(dynamic) => Content' is not a subtype of type '(dynamic) => String' of 'f' -- I dont even know where that f came from.
class ReadResponseModel {
List<String> content;
ReadResponseModel({this.content});
factory ReadResponseModel.fromJson(Map<String, dynamic> json) {
return ReadResponseModel(
content: json['content'] != null
? json['content']
.map<String>((json) => Content.fromJson(json))
.toList()
: null,
);
}
}
class Content {
final String imageID;
final String imgUrl;
final String retVal;
final String alarm;
final String account;
final String createAt;
final String location;
final String error;
Content({this.imageID,
this.imgUrl,
this.retVal,
this.alarm,
this.account,
this.createAt,
this.location,
this.error});
factory Content.fromJson(Map<String, dynamic> json) =>
Content(
imageID: json['image_id'],
imgUrl: json['s3_url'],
retVal: json['predict'],
alarm: json['alarm'],
account: json['account'],
createAt: json['create_at'],
location: json['location'],
);
}
The following code is just what I'm doing to connect all this to my widget:
APIService readService = new APIService();
readRequestModel.companyID = "123";
readService.readData(readRequestModel).then((value) async {
if (value != null) {
setState(() {
isApiCallProcess = false;
});
///Trying to call the fetched data and show it in the console:
print("Account: ${value.account}");
print("Returned Value: ${value.retVal}");
print("Image ID: ${value.imgUrl}");
}
I'm not entirely sure why I am getting these errors, and for method 2 I don't even know where that "f" came from. If anyone could shed some light on the subject it would be greatly appreciated.
You can copy paste run full code below
Step 1: Use List<Content> content; not List<String>
Step 2: Use List<Content>.from(json["content"].map((x) => Content.fromJson(x)))
Step 3: In sample JSON's image_url not equal model's s3_url, you need to modify to correct one
code snippet
class ReadResponseModel {
List<Content> content;
ReadResponseModel({this.content});
factory ReadResponseModel.fromJson(Map<String, dynamic> json) {
return ReadResponseModel(
content: json['content'] != null
? List<Content>.from(json["content"].map((x) => Content.fromJson(x)))
: null,
);
}
}
...
dynamic resBody = json.decode(jsonString);
ReadResponseModel model = ReadResponseModel.fromJson(resBody);
print(model.content[0].account);
output
I/flutter ( 4426): test#email.com
full code
import 'package:flutter/material.dart';
import 'dart:convert';
class ReadResponseModel {
List<Content> content;
ReadResponseModel({this.content});
factory ReadResponseModel.fromJson(Map<String, dynamic> json) {
return ReadResponseModel(
content: json['content'] != null
? List<Content>.from(json["content"].map((x) => Content.fromJson(x)))
: null,
);
}
}
class Content {
final String imageID;
final String imgUrl;
final String retVal;
final String alarm;
final String account;
final String createAt;
final String location;
final String error;
Content(
{this.imageID,
this.imgUrl,
this.retVal,
this.alarm,
this.account,
this.createAt,
this.location,
this.error});
factory Content.fromJson(Map<String, dynamic> json) => Content(
imageID: json['image_id'],
imgUrl: json['s3_url'],
retVal: json['predict'],
alarm: json['alarm'],
account: json['account'],
createAt: json['create_at'],
location: json['location'],
);
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
String jsonString = '''
{"status":200,
"content":[{"image_id":"151",
"image_url":"https:\\\/imageurl.jpg",
"returned_value":"14.0",
"alarm":"false",
"account":"test#email.com",
"create_at":"2020-11-17 07:13:42",
"location":"NY"
}]
}
''';
dynamic resBody = json.decode(jsonString);
ReadResponseModel model = ReadResponseModel.fromJson(resBody);
print(model.content[0].account);
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
From the above mentioned code I have created a sample example for you, basically you are messing up with the mode class.Take a look at the example below.
Json you provided:
{"status":200,
"content":[{"image_id":"151",
"image_url":"https:\\\/imageurl.jpg",
"returned_value":"14.0",
"alarm":"false",
"account":"test#email.com",
"create_at":"2020-11-17 07:13:42",
"location":"NY"
}]
}
Based on the json the model class below :
// To parse this JSON data, do
//
// final readResponseModel = readResponseModelFromJson(jsonString);
import 'dart:convert';
ReadResponseModel readResponseModelFromJson(String str) => ReadResponseModel.fromJson(json.decode(str));
String readResponseModelToJson(ReadResponseModel data) => json.encode(data.toJson());
class ReadResponseModel {
ReadResponseModel({
this.status,
this.content,
});
int status;
List<Content> content;
factory ReadResponseModel.fromJson(Map<String, dynamic> json) => ReadResponseModel(
status: json["status"],
content: List<Content>.from(json["content"].map((x) => Content.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"content": List<dynamic>.from(content.map((x) => x.toJson())),
};
}
class Content {
Content({
this.imageId,
this.imageUrl,
this.returnedValue,
this.alarm,
this.account,
this.createAt,
this.location,
});
String imageId;
String imageUrl;
String returnedValue;
String alarm;
String account;
DateTime createAt;
String location;
factory Content.fromJson(Map<String, dynamic> json) => Content(
imageId: json["image_id"],
imageUrl: json["image_url"],
returnedValue: json["returned_value"],
alarm: json["alarm"],
account: json["account"],
createAt: DateTime.parse(json["create_at"]),
location: json["location"],
);
Map<String, dynamic> toJson() => {
"image_id": imageId,
"image_url": imageUrl,
"returned_value": returnedValue,
"alarm": alarm,
"account": account,
"create_at": createAt.toIso8601String(),
"location": location,
};
}
And them main class for fetching the data and showing it in the listview.
import 'package:flutter/material.dart';
import 'package:json_parsing_example/model2.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: SampleApp(),
debugShowCheckedModeBanner: false,
);
}
}
class SampleApp extends StatefulWidget {
#override
_SampleAppState createState() => _SampleAppState();
}
class _SampleAppState extends State<SampleApp> {
bool _isLoading = false;
List<Content> list = List();
fetchData() async {
setState(() {
_isLoading = true;
});
String data =
await DefaultAssetBundle.of(context).loadString("json/parse.json");
// This is the above where you get the remote data
// Like var response = await get or post
final readResponseModel = readResponseModelFromJson(data);
list = readResponseModel.content;
setState(() {
_isLoading = false;
});
}
#override
void initState() {
super.initState();
fetchData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Your heading'),
),
body: Container(
child: _isLoading
? Center(child: CircularProgressIndicator())
: Column(
children: <Widget>[
ListView.builder(
shrinkWrap: true,
itemCount: list.length,
itemBuilder: (context, index) {
return Card(
child: Column(
children: <Widget>[
Text('${list[index].account}'),
Text('${list[index].location}')
],
),
);
})
],
)));
}
}
Let me know if it works
Can you try setting returned_value and image_id as int instead of string and give it a try ?

Flutter how to get specific value from json http response

I am using this code to upload json data to my nodejs server.
HttpClient client = new HttpClient();
var data = createSamplePayment().toJson();
var request = await client.openUrl('POST', Uri.parse(serverEndpoint + '/paymentrequests'));
request.headers.set(HttpHeaders.contentTypeHeader, 'APPLICATION/JSON');
request.write(json.encode(data));
var response = await request.close();
String reply = await response.transform(utf8.decoder).join();
print(reply);
The output from print(reply) is:
flutter: {"url":"https://paymentrequests/86C0110D","token":"w8SWavZNjOG","id":"C3C4966AF64D8CE194F5E3C"}
But I only want to get ”token” value. What can I do to fix that? I have tried in many different ways without success.
class DetailsModel {
String url;
String token;
String id;
DetailsModel({this.url, this.token, this.id});
DetailsModel.fromJson(Map<String, dynamic> json) {
url = json['url'];
token = json['token'];
id = json['id'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['url'] = this.url;
data['token'] = this.token;
data['id'] = this.id;
return data;
}
}
Firstly, convert your response into a Model, to do that you would need the above code. Then map your response.
DetailsModel details = DetailsModel.fromJson(response);
Then to access the details you can simply use.
dynamic token = details.token;
print(token); // w8SWavZNjOG
You can copy paste run full code below
I use the following code to simulate this case
You can do payloadFromJson(reply) and return payload.token
You can reference Payload class in full code
code snippet
Payload payloadFromJson(String str) => Payload.fromJson(json.decode(str));
...
Future<String> postWithClientCertificate() async {
...
Payload payload = payloadFromJson(reply);
print(payload.token);
return payload.token;
}
output
I/flutter ( 5995): w8SWavZNjOG
I/flutter ( 5995): token w8SWavZNjOG
full code
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'dart:convert';
Payload payloadFromJson(String str) => Payload.fromJson(json.decode(str));
String payloadToJson(Payload data) => json.encode(data.toJson());
class Payload {
Payload({
this.url,
this.token,
this.id,
});
String url;
String token;
String id;
factory Payload.fromJson(Map<String, dynamic> json) => Payload(
url: json["url"],
token: json["token"],
id: json["id"],
);
Map<String, dynamic> toJson() => {
"url": url,
"token": token,
"id": id,
};
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() async{
String token = await postWithClientCertificate();
print("token $token");
setState(() {
_counter++;
});
}
Future<String> postWithClientCertificate() async {
/*final serverEndpoint = 'https://1991269db78887f9e.ngrok.io';
HttpClient client = new HttpClient();
var data = createSamplePayment().toJson();
var request = await client.openUrl('POST', Uri.parse(serverEndpoint + '/paymentrequests'));
request.headers.set(HttpHeaders.contentTypeHeader, 'APPLICATION/JSON');
request.write(json.encode(data));
var response = await request.close();
String reply = await response.transform(utf8.decoder).join();
print(reply);*/
String reply =
'''{"url":"https://paymentrequests/86C0110D","token":"w8SWavZNjOG","id":"C3C4966AF64D8CE194F5E3C"}''';
Payload payload = payloadFromJson(reply);
print(payload.token);
return payload.token;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

Getting error type'_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable<dynamic>' while fetching data from API in flutter

I am new to flutter and I tried fetching data from API but I got the error
type'_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable<dynamic>'.
I am fetching news data from the API. I tried this for simple API and it worked and when I tried it for a complex API with some changes in the dart code I got this error.
Sorry if I didn't explain correctly. I have pasted all the code that has been used for this API.
I am not getting any solution. I am posting my code here.
post.dart
class Post {
List<Articles> articles;
Post({this.articles});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
articles: json['articles'].map((value) => new Articles.fromJson(value)).toList(),
);
}
}
article.dart
class Articles{
final String title;
final String description;
final String url;
final String urlToImage;
final String publishedAt;
final String content;
Articles({this.title, this.description, this.url, this.urlToImage, this.publishedAt, this.content});
factory Articles.fromJson(Map<String, dynamic> json) {
return Articles(
title: json['title'],
description: json['description'],
url: json['url'],
urlToImage: json['urlToImage'],
publishedAt: json['publishedAt'],
content: json['content'],
);
}
}
technology_post.dart
Future<List<Post>> fetchPost() async {
final response = await http.get('https://newsapi.org/v2/top-headlines?sources=techcrunch&apiKey=47ada2986be0434699996aaf4902169b');
if (response.statusCode == 200) {
var responseData = json.decode(response.body);
List<Post> posts = [];
for(var item in responseData){
Post news = Post.fromJson(item);
posts.add(news);
}
return posts;
} else {
throw Exception('Failed to load post');
}
}
class Technology extends StatelessWidget{
final Future<List<Post>> post;
Technology({Key key, this.post}) : super (key : key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FutureBuilder<List<Post>>(
future: post,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemBuilder: (BuildContext context, int index){
var dataStored = "";
for(var i = 0; i < 10; i++){
dataStored = snapshot.data.articles[i].title;
return ListTile(
title: Text(dataStored),
);
}
}
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
),
),
);
}
}
homescreen.dart
TabBarView(
children: [
Technology(post: fetchPost()),
Text('General'),
Text('Cricket')
]
I have posted all the required code I hope. If you want to see the API you can see that here
Sorry if I have pasted much code here.
Why am I getting this error and how can I resolve this.
Thanks in advance.
According to your json, there is no List but only Post as json is json object.
So change your fetchPost() function as follows:
Future<Post> fetchPost() async {
final response = await http.get(
'https://newsapi.org/v2/top-headlines?
sources=techcrunch&apiKey=$YOUR_API_KEY');
if (response.statusCode == 200) {
var responseData = jsonDecode(response.body);
var post = Post.fromJson(responseData);
return post;
} else {
throw Exception('Failed to load post');
}
}
NOTE : Remove your api key from your question and paste json only for privacy.
And change your technology class to
class Technology extends StatelessWidget {
final Future<Post> post;
Technology({Key key, this.post}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FutureBuilder<Post>(
future: post,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Text(snapshot.data.articles[0].publishedAt);
});
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
),
),
);
}
}
and your main problem is also that you have not cast json['articles'] to list. you should change Post.fromJson function to
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
articles: (json['articles'] as List).map((value) => new Articles.fromJson(value)).toList(),
);
}
This should solve your problem.
You should check correct response type Int with String. I see your API status: "ok" and sure you check correctly.