I did this but the (endPointUrl) after await get, is showing error, and having being have lot of issue, in which any url I use never responds always showing failed to locate localhost
import 'dart:convert';
import 'package:NewsApp/model/article_model.dart';
import 'package:http/http.dart';
class ApiService {
final endPointUrl =
"http://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=6ef7ae62a9e74ca2bcc7d634f9985146";
Future<List<Article>> getArticle() async {
Response res = await get(endPointUrl);
if (res.statusCode == 200) {
Map<String, dynamic> json = jsonDecode(res.body);
List<dynamic> body = json['articles'];
List<Article> articles =
body.map((dynamic item) =>
Article.fromJson(item)).toList();
return articles;
} else {
throw ("Can't get the Articles");
}
}
}
Your fetch method should be like this,
To fetch the whole data present in the given URL so use it where ever you want.
import 'dart:convert';
import 'package:NewsApp/model/article_model.dart';
import 'package:http/http.dart' as http;
class ApiService {
final endPointUrl =
"http://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=6ef7ae62a9e74ca2bcc7d634f9985146";
static Future<List<Article>> getArticle() async {
Response res = await http.get(Uri.parse(endPointUrl));
if (res.statusCode == 200) {
List json = jsonDecode(res.body);
// List<dynamic> body = json['articles'];
return
json .map((dynamic item) =>
Article.fromJson(item)).toList();
//return articles;
} else {
throw ("Can't get the Articles");
}
}
}
now suppose you retrieve the data in the following way.
FutureBuilder List<Article>(
future: ApiService.getArticle(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.bilder(
itemCount:snapshot.data.length,
itemBuilder: (context, position){
return Text(snapshot.data[position].article);
}
);
} else if (snapshot.hasError) {
return Text('error occurred');
} else {
return CircularProgressIndicator();
}
},
),
Related
I got FutureBuilder snapshot error when I parsing my JSON i got the:
type 'List' is not a subtype of type 'FutureOr<List>'
is it my Product model error or a parsing error?
my code
late Future<List<Product>> productFuture = getProducts();
static Future<List<Product>> getProducts() async {
var url = '${Constants.API_URL_DOMAIN}action=catalog&category_id=$id';
final response = await http.get(Uri.parse(url));
final body = jsonDecode(response.body);
print(body['data']);
return body['data'].map((e)=>Product.fromJson(e)).toList();
}
FutureBuilder<List<Product>>(
future: productFuture,
builder: (context, snapshot) {
print(snapshot);
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasData) {
final catalog = snapshot.data;
return buildCatalog(catalog!);
} else {
print('SNAPSOT DATA ${snapshot.data}');
return Text("No widget to build");
}
}),
Use List.from
return List.from(body['data'].map((e)=>Product.fromJson(e)));
static Future<List<Product>> getProducts() async {
var url = '${Constants.API_URL_DOMAIN}action=catalog&category_id=$id';
final response = await http.get(Uri.parse(url));
final body = jsonDecode(response.body);
print(body['data']);
return List.from(body['data'].map((e)=>Product.fromJson(e)));
}
Try to convert all List<Product> --> List<dynamic>
I want to get an image from an api and I get the error mentioned in the title.
class _ApiState extends State<Api> {
Future<CatData> fetchcat() async {
final response =
await http.get(Uri.parse('https://api.thecatapi.com/v1/images/search'));
// Appropriate action depending upon the
// server response
if (response.statusCode == 200) {
return CatData.fromJson(json.decode(response.body));
//return CatData.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else {
throw Exception('Failed to load album');
}
}
late Future<CatData> futureAlbum;
#override
void initState() {
super.initState();
futureAlbum = fetchcat();
}
#override
Widget build(BuildContext context) {
return FutureBuilder<CatData>(
future: fetchcat(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Image.network(snapshot.data!.imagen);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
);
}
}
here the class model:
class CatData {
String imagen;
CatData({required this.imagen});
factory CatData.fromJson(Map<String, dynamic> json) {
return CatData(
imagen: json['url'],
);
}
}
If I get an answer please, I would like you to explain to me the reason for the problem. because I always get this kind of errors when I consume API's.
"receives one value but expects another"
https://api.thecatapi.com/v1/images/search
Well, json.decode(response.body) gives you back a List<dynamic>, but you declared the method fromJson to accept one argument of type Map<String, dynamic>, thus the incompatibility.
You can change the signature of the method fromJson and set it to List<dynamic>. Then you could access it with json[0].url, json[0]['url'] or {url} = json[0].
I tested the following code in https://dartpad.dev and works like a charm now.
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<CatData> fetchcat() async {
final response =
await http.get(Uri.parse('https://api.thecatapi.com/v1/images/search'));
// Appropriate action depending upon the
// server response
if (response.statusCode == 200) {
return CatData.fromJson(json.decode(response.body));
//return CatData.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else {
throw Exception('Failed to load album');
}
}
class CatData {
String imagen;
CatData({required this.imagen});
factory CatData.fromJson(List<dynamic> json) {
return CatData(
imagen: json[0]['url']
);
}
}
void main() async {
CatData catData = await fetchcat();
print(catData.imagen);
}
You probably making mistake on casting. first make sure what kind of data you are retrieving means is it key-value pair { "url" : "www...." } or List [{"url" :"www...} , { "url": " www..."}]
if its key-value pairs then decode it as follows:
final decoded = json.decode(response.body) as Map<String, dynamic>;
final _catData = CataData.fromJson(decoded);
or if its list of urls then do it as follows:
final _decoded = json.decode(response.body) as List<dynamic>;
final _catsData = _decoded.map((e) => CatData.fromJson(e as Map<String, dynamic>)).toList();
I am learning to use api and all data in my interface is showing as null
in this section to understand where the problem lies i change ! with ?
How can I check if there is a problem while pulling the data?
I deleted the irrelevant parts to shorten the code.
WeatherApiClient client = WeatherApiClient();
Hava? data;
Future<void> getData()async{
data = await client.getCurrentWeather("London");
}
#override
Widget build(BuildContext context) {
return MaterialApp(
body: FutureBuilder(
future: getData(),
builder: (context, snapshot){
if(snapshot.connectionState==ConnectionState.done){
return Column(
children: [
GuncelVeri(Icons.wb_sunny_rounded, "${data?.derece}", "${data?.sehir}"),
bilgiler("${data?.humidity}","${data?.feels_like}", "${data?.pressure}","${data?.description}"),],
);
}
else if(snapshot.connectionState == ConnectionState.waiting){
return Center(
child: CircularProgressIndicator(),
);
}
return Container();
},
)
),
);
}
}
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:weatherapp/model.dart';
class WeatherApiClient{
Future<Hava>? getCurrentWeather(String? location)async{
var endpoint = Uri.parse(
"https://api.openweathermap.org/data/2.5/weather?q=$location&appid=9b6ece44d1233c111b86cacb5e3617f1&units=metric&lang=tr"
);
var response = await http.get(endpoint);
var body = jsonDecode(response.body);
print(Hava.fromJson(body));
return Hava.fromJson(body);
}
}
Your are getting Null because you are trying to access the Hava class which have not been initilized yet.
You are printing print(Hava.fromJson(body));
before return Hava.fromJson(body);
First you want to check if what responce is getting from the http call.
for that you can just print the http responce like this:-
print(responce.body)
Then you can see what's the responce is.
They you can do return Hava.fromJson(body);
The right way
Check the status code of the responce, if the responce is 200 the cast the json responce to the model class or show an error
Refer code
Future<Profileclass> fetchprofile() async {
String tokenFetch = await getStringValuesSF();
return await Dio()
.get(urlprofiledio,
options: Options(
headers: {
'Authorization': 'Bearer $tokenFetch',
},
))
.then((response) {
if (response.statusCode == 200) {
return Profileclass.fromJson(jsonDecode(response.toString()));
} else {
throw Exception('Failed to load profile');
}
});
}
Thank you
i want to return json object list but i dont know how
i'm using the sample doc from flutter the
here is my code
Future<Album> fetchAlbum() async {
final response =
await http.get('https://vpic.nhtsa.dot.gov/api/vehicles/getmodelsformake/honda?format=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');
}
}
class Album {
final String userId;
final List <String> Cm;
Album({this.userId, this.Cm});
factory Album.fromJson(Map<String, dynamic> json) {
return Album(
userId: json['Results'][0]['Make_Name'],
Cm: for( var i = 0 ; i < json['Count']; i++ ) {
Cm.add(json['Results'][i]['Make_Name']);
}
);
}
}
the error in Cm: for... line
In your code snippet you did not created a class to refer Results list. Try bellow code snippet.
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<Album> fetchAlbum() async {
final response = await http.get(
'https://vpic.nhtsa.dot.gov/api/vehicles/getmodelsformake/honda?format=json');
if (response.statusCode == 200) {
return Album.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to load album');
}
}
class Album {
int count;
String message;
String searchCriteria;
List<Results> results;
Album({this.count, this.message, this.searchCriteria, this.results});
Album.fromJson(Map<String, dynamic> json) {
count = json['Count'];
message = json['Message'];
searchCriteria = json['SearchCriteria'];
if (json['Results'] != null) {
results = new List<Results>();
json['Results'].forEach((v) {
results.add(new Results.fromJson(v));
});
}
}
}
class Results {
int makeID;
String makeName;
int modelID;
String modelName;
Results({this.makeID, this.makeName, this.modelID, this.modelName});
Results.fromJson(Map<String, dynamic> json) {
makeID = json['Make_ID'];
makeName = json['Make_Name'];
modelID = json['Model_ID'];
modelName = json['Model_Name'];
}
}
As the for-loop is not returning the list to the cm field, you may try using .map to do the mapping and return it.
Cm: json['Results'].map((e)=>e['Make_Name']).toList()
First off, Flutter is a Framework for Dart language, so you don't need Flutter to run that code. Run code below on console:
import 'dart:convert';
import 'package:http/http.dart' as http;
class NetService {
static Future fetchJsonData(String url) {
return
http.get(url)
.then((response) => response?.statusCode == 200 ? jsonDecode(response.body) : null)
.catchError((err) => print(err));
}
static Future<void> fetchCarModels() {
return
fetchJsonData('https://vpic.nhtsa.dot.gov/api/vehicles/getmodelsformake/honda?format=json')
.then((response) {
if (response != null) {
final Map<String, dynamic> data = response;
print('''
Count : ${data["Count"]}
Message : ${data["Message"]}
Search Criteria : ${data["SearchCriteria"]}
Models :
${(data["Results"] as List)?.fold<String>("", (m, e) => m + (e as Map<String, dynamic>)["Model_Name"] + ", ")}
'''
);
}
})
.catchError((err) => print(err));
}
}
void main(List<String> arguments) async {
await NetService.fetchCarModels();
}
how can I read the HTTP post response with the class return type?
my class is
class ContactModal {
String code;
String status;
String name;
ContactModal({this.code, this.status, this.name});
factory ContactModal.fromJson(Map<String, dynamic> json) {
return ContactModal(
code: json['code'],
status: json['status'],
name: json['name']
);
}
}
and my HTTP request is
class ApiClient {
Future<ContactModal> getDetails(String token) async {
print("inside get file "+token);
var response = await http
.get(Uri.parse(this.apiBaseUrl + "/file-list/"), headers: {
"Accept": "application/json",
"Authorization": token
});
if (response.statusCode == 200) {
print("Json response"+response.body);
return ContactModal.fromJson(json.jsonDecode(response.body));
} else {
print("Json exception response");
throw Exception('Failed to fetch access token');
}
}
}
my builder is
body: new Container(
child: new FutureBuilder(
future: apiClient.getFileDetails(this.accessToken),
builder: (context, snapshot) {
print(" prefs.getString('accessTokenValue') "+snapshot.data);
if (snapshot.hasData) {
print("Snap shot data : "+snapshot.data);
new ContactsList(_buildContactList(snapshot));
} else if (snapshot.hasError) {
return new Text("${snapshot.error}");
}
// By default, show a loading spinner
return new CircularProgressIndicator();
},
),
),
my api will return the response List[ContactModal]()
How can i read the all data and am getting everytime snapshot result null.
Your response contains array of contact json. So you might have to build the contact list and return like below.
var jsonArray = json.jsonDecode(response.body);
var contactList = jsonArray.map((json) => ContactModal.fromJson(json)).toList();
Return type of getDetails will be Future<List<ContactModal>>.