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
Related
Hi guys I'm new to Flutter
I'm trying to fetch the data from http.post method using FutureBuilder and snapshot.data but it keeps returning CircularProgressIndicator which is means snapshot has no data.
Future postDataTransaksi() async {
try {
http.Response response = await http.post(
Uri.parse('https://ignis.rumahzakat.org/donol/listTransaksi'),
body: {
'---': '---',
'---': '---',
},
headers: {
'access-token': '---'
});
if (response.statusCode == 200) {
var data = jsonDecode(response.body);
} else {}
} catch (e) {
print(e.toString());
}
}
This is my post method code.
FutureBuilder(
future: postDataTransaksi(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return Container(child: Text(snapshot.data[0]['id']));
} else {
return const Center(child: CircularProgressIndicator());
}
})
And this is how I try to fetch the data
Change your builder to this:
if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
return Container(child: Text(snapshot.data[0]['id']));
} else {
return const Center(child: CircularProgressIndicator());
}
and also change your future to this"
Future<List> postDataTransaksi() async {
try {
http.Response response = await http.post(
Uri.parse('https://ignis.rumahzakat.org/donol/listTransaksi'),
body: {
'---': '---',
'---': '---',
},
headers: {
'access-token': '---'
});
if (response.statusCode == 200) {
var data = jsonDecode(response.body);
return data;// <--- add this
}
return [];// <--- add this
} catch (e) {
print(e.toString());
return [];// <--- add this
}
}
In a Future Builder im trying to use two methods with different types, both of them fetch data from the api,
the main problem that im having is that both of the function have different types, so im having problem on putting
the two methods because of their types. I tried using
Future.wait(Future[]) aswell but i was getting many errors, there errors where mostly on List,
im still trying to learn how Future Builders work, i worked with FutureBuilders before but didnt have to use two functions inside the FutureBuilder. So if anyone could implement their solution on my code, that would really help and maybe add some comments on why did you make the change so i learn for the future. As a bonus im getting the List is not a subtype of type Map<String, dynamic> error aswell so if anyone could help with that too it would be very helpful. Tried looking into stack over flow answers for that but i couldnt figure it out since i was getting an error on this part
buildSwipeButton() {
return MenuPage(
sendData: fetchLoginData()// i was getting error here,
);
}
buildSwipeButton() {
return MenuPage( // other class name from a different file
sendData: fetchLoginData(),
);
}
buildSwipeButton2() {
return MenuPage( // other class name from a different file
sendData2: fetchWorkingLocationData(),
);
}
Future<LoginData>? fetchLoginData() async {
var url = 'https://dev.api.wurk.skyver.co/api/employees';
String basicAuth = 'Basic ' +
base64Encode(
utf8.encode('${emailController.text}:${passwordController.text}'),
);
var response = await http.get(
Uri.parse(url),
headers: <String, String>{'authorization': basicAuth},
);
print(response.body);
if (response.statusCode == 200) {
print(response.statusCode);
return LoginData.fromJson(
jsonDecode(response.body),
);
} else {
throw Exception('Failed to load LoginData');
}
}
Future<WorkingLocationData>? fetchWorkingLocationData() async {
var url = 'https://dev.api.wurk.skyver.co/api/locations';
String basicAuth = 'Basic ' +
base64Encode(
utf8.encode('${emailController.text}:${passwordController.text}'),
);
var response2 = await http.get(
Uri.parse(url),
headers: <String, String>{'authorization': basicAuth},
);
print(response2.body);
if (response2.statusCode == 200) {
print(response2.statusCode);
return WorkingLocationData.fromJson(
jsonDecode(response2.body),
);
} else {
throw Exception('Failed to load Working Location Data');
}
}
// other file where im trying to use Future Builder
late LoginData data;
Future<LoginData>? sendData;
Future<WorkingLocationData>? sendData2;
body: FutureBuilder<LoginData>(
future: sendData, // trying to use sendData and sendData2
builder: (context, snapshot) {
if (snapshot.hasData) {
LoginData? data1 = snapshot.data;
data = data1!;
print(data.loginPhoneNumber);
return afterLoginBody();
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
return Center(child: const CircularProgressIndicator());
},
),
),
Try below code hope its help to you.
late LoginData data;
Future<LoginData>? sendData;
Future<WorkingLocationData>? sendData2;
body: FutureBuilder<LoginData>(
Future.wait([sendData, sendData2]),
builder: (context, AsyncSnapshot<List<dynamic>> snapshot{
snapshot.data[0]; //sendData
snapshot.data[1]; //sendData2
},
),
),
You can try this:
Future? _future;
Future<dynamic> sendData() async {
final data1 = await sendData1();
final data2 = await sendData2();
return [data1, data2];
}
#override
void initState() {
_future = sendData()();
super.initState();
}
///
FutureBuilder(
future: _future,
builder: (context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CupertinoActivityIndicator();
}
if (snapshot.hasError) {
return SomethingWentWrong();
}
final data1= snapshot.data[0] as YourDataModel;
final data2 = snapshot.data[1] as YourDataModel;
});
I am trying to connect to Yahoo Finance API within my Flutter application, and I canĀ“t connect.
I've seen guidance to connect to the API in different languages but there is no official guidance for Dart language.
I have the following method to connect to the API:
Future<double> getStockPrice(String symbol) async {
//var client = http.Client();
var url = 'https://apidojo-yahoo-finance-v1.p.rapidapi.com';
var apiStr = "/stock/v2/get-summary";
var headers = {'x-rapidapi-key': "809135c7c7mshf35d1107bf50919p15c9fajsn37166d6b1bfc",
'x-rapidapi-host': "apidojo-yahoo-finance-v1.p.rapidapi.com"};
var params = {'symbol': 'AMRN', 'region': 'US'};
var response = await http.get(Uri.https(url, apiStr,params),headers: headers);
//https://apidojo-yahoo-finance-v1.p.rapidapi.com/stock/v2/get-summary?symbol=AMRN®ion=US
//var response = await http.get(Uri.https(url, apiStr, params));
print('RESPONSE STATUS code: ${response.statusCode}');
if (response.statusCode == 200) {
print('RESPONSE STATUS code: ${response.statusCode}');
var json = jsonDecode(response.body);
String value = json['price']['regularMarketOpen']['raw'];
return double.parse(value);
} else {
return 0.0;
}
}
And I get null from this method. I guess it can be a matter of getting value variable, maybe I am not traversing the JSON tree correctly. But I don't see why.
Then I retrieve the data from the API in the following screen:
import 'package:flutter/material.dart';
import 'package:stock_analyzer/api_method/webService.dart';
class TestScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
Future<String> test = YahooFinanceService().getWebSite('symbol');
return Scaffold(
appBar: AppBar(
title: Text('test'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FutureBuilder<String>(
future: test,
builder: (context, AsyncSnapshot<String> snapshot){
return Text('Result: ${snapshot.data}');
})
],
),
);
}
}
In this screen I get null. So, snapshot.data = null
Thanks
The 401 error shows that you are not authorized to make a post request, I think the error is that you are doing post instead of get.
Try changing:
var response = await client.post(url, body: headers);
To:
var response = await client.get(url, headers: headers);
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();
}
},
),
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>>.