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
}
}
Related
here is my code to catch data from web:
it crashes with multiple kind of exeptions each time, i want to show the error on screen but do not crash the app and terminate it
Future<SCoin> fetchCoinData(int giveMeIndex) async {
final response = await http.get(Uri.parse(url));
final jsonresponse = json.decode(response.body);
if (response.statusCode == 200) {
for (var i in jsonresponse) {
var coinItem = SCoin(
name: i['name'],
image: i['image'],
current_price: i['current_price']);
coins.add(coinItem);
}
return SCoin.fromJson(jsonresponse[giveMeIndex]);
} else {
throw Exception(response.statusCode);
}
}
and this my widget to show data:
FutureBuilder<SCoin>(
future: fetchCoinData(2),
builder:
(context, snapshot) {
if (snapshot.hasData) {
return Column(
children: [
Container(
width: 45,
height: 45,
child: Image.network(
snapshot.data!
.coinImage),
),
Text(snapshot
.data!.name),
Text(snapshot.data!
.current_price
.toString())
],
);
} else if (snapshot
.hasError) {
return Text(
'${snapshot.error}');
}
// By default, show a loading spinner.
return const CircularProgressIndicator();
}),
this is done with the try and catch to try running a code, if there is any error you can evaluate and catch it, and the future you set to the FutureBuilder
should be wrapped inside another function that tries it and then catch on error like :
Future tryCatchMethod(int number) async {
try {
await fetchCoinData(number);
} on Exception catch(error) {
// Here throw you exceptions and take actions based on your needs
}}
and assigning that new method to the FutureBuilder
future: tryCatchMethod;
this will try running your Future method, if it succeeds, then nothing will happen, normally, but if something wrong happened and an error threw it will execute the catch block code.
Try the following code:
Future<SCoin> fetchCoinData(int giveMeIndex) async {
try {
final response = await http.get(Uri.parse(url));
final jsonresponse = json.decode(response.body);
if (response.statusCode == 200) {
for (var i in jsonresponse) {
var coinItem = SCoin(
name: i['name'],
image: i['image'],
current_price: i['current_price'],
);
coins.add(coinItem);
}
return SCoin.fromJson(jsonresponse[giveMeIndex]);
} else {
throw Exception(response.statusCode);
}
} catch (e) {
throw Exception(e);
}
}
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 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 get List values as ints one by one.
where movieId requires an int value.
help me please
thank you
Future<MovieDetailModel> getMovieDetail(int? movieId) async {
try {
http.Response res = await http
.get(Uri.parse('$mainUrl/movie/$**movieId**?$apiKey&language=ko-KR'))
.timeout(Duration(seconds: 8),
onTimeout: () async => new http.Response('{}', 404));
if (res.statusCode == 404) {
return MovieDetailModel.fromJson({});
}
Map<String, dynamic> result = jsonDecode(res.body);
MovieDetailModel movies = MovieDetailModel.fromJson(result);
return movies;
} catch (e) {
print('MovieDetail $e');
}
return MovieDetailModel.fromJson({});
}
where user.userMovieId value is List .
Widget userMovie(UserModel user) {
return FutureBuilder(
future: this._movieDetailProvider.movies(**user.userMovieId!**),
builder:
(BuildContext context, AsyncSnapshot<MovieDetailModel> snapshot) {
if (snapshot.hasData) {}
Provider.
Future<MovieDetailModel> movies(int movieId) async {
MovieDetailModel movieList = await _movieRepo.getMovieDetail(movieId);
notifyListeners();
return movieList;
}
I am new in BLOC and I am trying to read respond from api.. but whenever I call stream builder... my widget always stops in wait... here is my code
here is api provider file
class Provider {
final _url = '...';
Future<List<LoginRespon>> login(a, b) async {
List<LoginRespon> datalogin = [];
try {
bool trustSelfSigned = true;
HttpClient httpClient = new HttpClient()
..badCertificateCallback =
((X509Certificate cert, String host, int port) =>
trustSelfSigned);
IOClient http = new IOClient(httpClient);
final response = await http.post(_url,
headers: {
HttpHeaders.contentTypeHeader: 'application/json',
},
body: json.encode({
"aa": a,
"bb": b,
}));
Map<String, dynamic> responseJson = json.decode(response.body);
if (responseJson["status"] == "200") {
datalogin.add(LoginRespon(
status: responseJson['status'],
data: Data(
name: responseJson['data']['name'],
position: responseJson['data']['pos'])));
return datalogin;
} else {
print("ppp");
}
} on Exception {
rethrow;
}
return datalogin;
}
}
and here is for stream builder
isClick
? StreamBuilder(
stream: bloc.login(),
builder: (context, snapshot) {
if (snapshot.hasData) {
print(snapshot.data);
return Text("success");
} else if (snapshot.hasError) {
return Text(
snapshot.error.toString());
}
return Text("wait..");
},
)
: FlatButton(
child: Text("Login"),
onPressed: () {
setState(() {
isClick = true;
});
},
),
is there a way so that I can call print(snapshot.data) inside if (snapshot.hasData)
You need to pass argument which required in method otherwise it will not successfully responce (200) and it will throw error.