Access Data from API in flutter - flutter

I want to access data from the API below.
"https://api.categen.com/api.php/recent_activity/1"
and Want to print in text.
Please help me.
Moreover, there is 3 classes
Home . dart file.
DataService . dart file.
Model . dart file
I tried below code.
Home.dart .
import 'dart:convert';
import 'package:categen_api_test/data_service.dart';
import 'package:categen_api_test/model.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final _dataService = DataService();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Categen API"),
),
body: Center(
child: ElevatedButton(
child: Text("Click me"),
onPressed: () {
_getlist();
},
),
),
);
}
void _getlist() async {
final response = await _dataService.getData();
print(response.name);
}
}
DataService
import 'dart:convert';
import 'package:categen_api_test/model.dart';
import 'package:http/http.dart' as http;
class DataService {
Future<ModelData> getData() async {
final String url = "https://api.categen.com/api.php/recent_activity/1";
final uri = Uri.https('api.categen.com', '/api.php/recent_activity/1');
final response = await http.get(uri);
print(response.body);
final json = jsonDecode(response.body);
return ModelData.fromJson(json);
}
}

First create a model like this:
class Model {
final String name;
final String location;
final String action_value;
final String item;
Model(this.name, this.location, this.action_value, this.item);
List<Model> getList(json) {
List<Model> tempList = []
json['records'].forEach((model)=> tempList.add(
Model(
model["name"],
model["location"],
model["action_value"],
model["item"]
)
)
);
return tempList;
}
}
Then create a function to fetch the data:
Future<List<Model>> fetchData() async {
final response = await http.get('https://api.categen.com/api.php/recent_activity/1');
if (response.statusCode == 200) {
return Model.getList(response.body);
} else {
throw Exception('Unable to fetch products from the REST API');
}
}
call the fetch data function in the init state of the HomePage Widget
late Future<List<Model>> futureData;
void initState() {
super.initState();
futureData = fetchData();
}
what is left to do now is to get your data using a FutureBuilder Widget.
and display the list of your data
FutureBuilder<Model>(
future: futureData,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Column(
children: snaphot.map((e)=>Text(e.name)).toList()
);
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
return const CircularProgressIndicator();
},
)
if you want to reload the data on the click of a button, then call the fetch data whenever the button is clicked and then rebuild state of the Homepage widget like shown below
onPressed: (){
setState(
(){
futureData = fetchData();
}
);
}

Try below code hope its helpful to you. If you get data from API refer my answer here or here or here hope it's helpful to you
Create your home widget:
Center(
child: ElevatedButton(
child: Text('Pressed Me'),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Jobs(),
),
),
),
),
Create your List Widget.
Your API Call function:
Future<List<dynamic>> getJobsData() async {
String url = 'https://api.categen.com/api.php/recent_activity/1';
var response = await http.get(Uri.parse(url), headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
});
return json.decode(response.body)['records'];
}
Your Widget:
Column(
children: [
Expanded(
child: Center(
child: FutureBuilder<List<dynamic>>(
future: getJobsData(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
var name = snapshot.data![index]['name'];
var location = snapshot.data![index]['location'];
var item = snapshot.data![index]['item'];
var action = snapshot.data![index]['action_value'];
var date = snapshot.data![index]['created_timestamp'];
return Card(
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.green.shade300),
borderRadius: BorderRadius.circular(15.0),
),
child: ListTile(
leading: Text(
action.toString(),
),
title: Text(name),
subtitle: Text(
location + '\n' + date,
),
trailing: Text(item),
),
);
},
),
);
}
return CircularProgressIndicator();
},
),
),
),
],
),
Your all class:
class Jobs extends StatelessWidget {
Future<List<dynamic>> getJobsData() async {
String url = 'https://api.categen.com/api.php/recent_activity/1';
var response = await http.get(Uri.parse(url), headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
});
return json.decode(response.body)['records'];
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Jobs'),
),
body: Column(
children: [
Expanded(
child: Center(
child: FutureBuilder<List<dynamic>>(
future: getJobsData(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
var name = snapshot.data![index]['name'];
var location = snapshot.data![index]['location'];
var item = snapshot.data![index]['item'];
var action = snapshot.data![index]['action_value'];
var date = snapshot.data![index]['created_timestamp'];
return Card(
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.green.shade300),
borderRadius: BorderRadius.circular(15.0),
),
child: ListTile(
leading: Text(
action.toString(),
),
title: Text(name),
subtitle: Text(
location + '\n' + date,
),
trailing: Text(item),
),
);
},
),
);
}
return CircularProgressIndicator();
},
),
),
),
],
),
);
}
}
Your Home widget output screen->
Your List Widget output screen->

Related

flutter carousel slider doesn't refresh items

i am new at flutter, so i tried to implement carousel slider with images, i receive an List with my model from server and i created widget but it shows only 1 item from 18... I mean it always show 1 item, but all list is passed
But if i make hot reload then i receive all items, i hope i could explain... my dart code
import 'dart:convert';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:vltest/Models/_easyloaderslist.dart';
import 'Models/_workers.dart';
import 'Widgets/navigation_drawer_widget.dart';
import 'database.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
late List<EasyLoadersList> imgList = List.empty();
class Landing extends StatefulWidget {
#override
_LandingState createState() => _LandingState();
}
Future<List<EasyLoadersList>> _getLoaders(Workers workers) async {
final response = await http.get(
Uri.parse(
'http://url'),
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer ${workers.token}"
});
if (response.statusCode == 200) {
Iterable l = json.decode(response.body);
List<EasyLoadersList> loaders = List<EasyLoadersList>.from(
l.map((model) => EasyLoadersList.fromJson(model)));
return loaders;
} else {
throw Exception('Failed to load album');
}
}
List<T> map<T>(List list, Function handler) {
List<T> result = [];
for (var i = 0; i < list.length; i++) {
result.add(handler(i, list[i]));
}
return result;
}
showWorkerDialog(BuildContext context, Workers album) {
// set up the button
Widget okButton = TextButton(
child: Text("OK"),
onPressed: () {
Navigator.pop(context);
},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text(album.name),
content: Text("Hi, ${album.name}"),
actions: [
okButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
class _LandingState extends State<Landing> {
String _username = "";
late List<EasyLoadersList> loaders = List.empty();
int _current = 0;
#override
void initState() {
super.initState();
_loadUserInfo();
}
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: NavigationDrawerWidget(),
appBar: AppBar(
title: Text('User info'),
),
body: RefreshIndicator(
onRefresh: () async {
_loadUserInfo();
},
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CarouselSlider.builder(
itemCount: imgList.length,
itemBuilder: (context, index, realIndex) {
if (imgList.length != 0) {
return buildImage(imgList[index]);
} else {
return loadingData(context);
}
},
options: CarouselOptions(height: 500),
),
]),
),
),
);
}
Widget buildImage(EasyLoadersList loadersList) => Column(
mainAxisSize: MainAxisSize.max,
children: [
AspectRatio(
aspectRatio: 1,
child: Image.network(
loadersList.url,
fit: BoxFit.fill,
),
),
const SizedBox(
height: 30,
),
Text("Address :" + loadersList.shopAddress),
Text("Serial:" + loadersList.serialNumber),
Text("Hours :" + loadersList.currentMotoHours),
Text("Current:" + loadersList.currentMotoHoursUntilTO),
Text("Next:" + loadersList.remainsMotoHoursUntilTO),
Text("Last Use:" + loadersList.lastMotoHoursEditDate),
],
);
Widget loadingData(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(
'Loading...',
style: Theme.of(context).textTheme.headline6,
),
CircularProgressIndicator(
semanticsLabel: 'Loading...',
),
],
),
),
);
}
Future<void> _loadUserInfo() async {
Workers workers = await DBProvider.db.getWorkerInfo();
final prefs = await SharedPreferences.getInstance();
showWorkerDialog(context, workers);
imgList = await _getLoaders(workers);
}
}
Cant see any setState to update the UI. try adding setState on end of refresh like.
onRefresh: () async {
await _loadUserInfo();
setState((){});
},
And on initState
_loadUserInfo().then((value) {setState((){})}):
Or
Future<void> _loadUserInfo() async {
.....
imgList = await _getLoaders(workers);
setState((){});
}

The search bar does not return any results

I am trying to add a search function in my flutter app, the search bar is showing and there's not errors but its not working and it doesn't return any results.
the data list is from an API that I already called using the rest API
// ignore_for_file: use_key_in_widget_constructors, avoid_print, avoid_unnecessary_containers, curly_braces_in_flow_control_structures, prefer_const_constructors, non_constant_identifier_names, unnecessary_new, avoid_function_literals_in_foreach_calls, unused_import, avoid_types_as_parameter_names, unused_label
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:myapp2/Service_Request/SR.dart';
import 'package:myapp2/main.dart';
import 'package:myapp2/Service_Request/second.dart';
import '../Classes/demandes.dart';
import 'SR_details.dart';
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DataFromAPI(),
);
}
}
class DataFromAPI extends StatefulWidget {
#override
_DataFromAPIState createState() => _DataFromAPIState();
}
List<Attributes> _MyAllData = [];
var _srAttributes = [];
class _DataFromAPIState extends State<DataFromAPI> {
#override
void initState() {
loadData().then((value) {
setState(() {
_srAttributes.addAll(value);
});
});
super.initState();
}
Future<List<Sr>> loadData() async {
try {
var response = await http.get(Uri.parse(
'http://192.168.1.30:9080/maxrest/rest/mbo/sr/?_lid=azizl&_lpwd=max12345m&_format=json'));
if (response.statusCode == 200) {
final jsonBody = json.decode(response.body);
Demandes data = Demandes.fromJson(jsonBody);
final srAttributes = data.srMboSet.sr;
return srAttributes;
}
} catch (e) {
throw Exception(e.toString());
}
throw Exception("");
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: new Scaffold(
appBar: AppBar(
title: Text('Liste des Demandes'),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () => Navigator.push(
context, MaterialPageRoute(builder: (context) => SR()))),
),
body: FutureBuilder<List<Sr>?>(
future: loadData(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator();
} else {
return new ListView.builder(
itemCount: snapshot.data?.length,
itemBuilder: ((_, index) {
return index == 0
? _searchbar()
: new ListTile(
title: new Card(
margin: new EdgeInsets.symmetric(
vertical: 2.0, horizontal: 8.0),
elevation: 10,
child: new ListTile(
title: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(padding: new EdgeInsets.all(2.0)),
new Text(
'Ticket ID : ${snapshot.data![index].attributes.ticketid.content}'),
new Text(
'status : ${snapshot.data![index].attributes.status.content}'),
new Text(
'description : ${snapshot.data![index].attributes.description?.content}'),
new Text(
'Reported by : ${snapshot.data![index].attributes.reportedby.content}'),
new Text(
'Reoprt date : ${snapshot.data![index].attributes.statusdate.content}'),
],
),
trailing: Icon(Icons.arrow_forward_ios_rounded),
),
),
onTap: () {
Navigator.of(context)
.push(
new MaterialPageRoute(
builder: (BuildContext context) =>
new SrDetailsScreen(
sr: snapshot.data![index]),
),
)
.then((data) {});
});
}),
);
}
},
),
),
);
}
_searchbar() {
return Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
decoration: InputDecoration(hintText: "Search ..."),
onChanged: (text) {
text = text.toLowerCase();
setState(() {
_srAttributes = _MyAllData.where((srAttributes) {
var idticket = srAttributes.description!.content.toLowerCase();
return idticket.contains(text);
}).toList();
});
},
),
);
}
}
FutureBuilder loads values of current future. You are assigning a function result to FutureBuilder so its value always changes dynamically.
Create variable to keep Future's value.
Future<List<Sr>>? dataToLoad;
Whenever you want to load data from server ( for example, on text changed ):
setState((){
dataToLoad = loadData();
});
And use it in FutureBuilder:
FutureBuilder<List<Sr>?>(
future: dataToLoad,

Setting login cookies in the rest of headers requests Flutter

i'm trying to set the login cookies to the rest of the get requests.
so i use http pachakge and store the login cookies with sharedPreferences and use it in the get request by adding an update function
but i have a problem that when i go to the page i get 400 response just refreshing the page and i get my data and response 200
is there any other solution for setting cookies in the others get requests headers ?
or is there a solution for my bug ?
codes images : [https://ibb.co/kD3dDc9]
[https://ibb.co/25p5fZr]
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'package:valomnia_reports/Screens/Superviseur%20Screens/SideBar.dart';
import 'user_model.dart';
class SellersPage extends StatefulWidget {
const SellersPage({Key? key}) : super(key: key);
#override
_SellersPage createState() => _SellersPage();
}
class _SellersPage extends State<SellersPage> {
String? finalEmail;
Future? _futureData;
String? rawCookie;
// ignore: must_call_super
void initState() {
getValidationData();
super.initState();
_futureData = getUserApi();
}
Future getValidationData() async {
final SharedPreferences sharedPreferences2 =
await SharedPreferences.getInstance();
var obtainedEmail2 = sharedPreferences2.getString("rawCookie");
setState(() {
rawCookie = obtainedEmail2;
print(rawCookie);
});
}
List<UserModel> userList = [];
Map<String, String> headers = {};
Future<List<UserModel>> getUserApi() async {
http.Response response = await http.get(
Uri.parse('https://valomnia.herokuapp.com/superviseur/getAllVendeurs'),
headers: headers);
response.headers['set-cookie'] = rawCookie!;
updateCookie(response);
var data = jsonDecode(response.body.toString());
String? cookies = response.headers['set-cookie'];
if (response.statusCode == 200) {
for (Map i in data) {
userList.add(UserModel.fromJson(i));
}
print("Cookie : $cookies");
print("200");
return userList;
} else {
print("400");
print(rawCookie);
print(cookies);
return userList;
}
}
void updateCookie(http.Response response) {
String? rawCookie2 = response.headers['set-cookie'];
if (rawCookie2 != null) {
int index = rawCookie2.indexOf(';');
headers['cookie'] =
(index == -1) ? rawCookie2 : rawCookie2.substring(0, index);
}
}
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
new GlobalKey<RefreshIndicatorState>();
Future<Null> _refresh() {
return getUserApi().then((userList) {
setState(() => userList = userList);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: NavigationDrawerWidget(),
appBar: AppBar(
title: Text(
'Sellers list',
),
centerTitle: true,
backgroundColor: Colors.green,
),
body: Column(
children: [
Expanded(
child: FutureBuilder(
future: _futureData,
builder: (context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
} else {
return RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: _refresh,
child: ListView.builder(
itemCount: userList.length,
itemBuilder: (context, index) {
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
ReusbaleRow(
title: 'Id',
value:
snapshot.data![index].id.toString()),
ReusbaleRow(
title: 'Name',
value: snapshot.data![index].name
.toString()),
ReusbaleRow(
title: 'Username',
value: snapshot.data![index].username
.toString()),
ReusbaleRow(
title: 'DateCreated',
value: snapshot.data![index].email
.toString()),
],
),
),
);
}),
);
}
},
),
)
],
),
);
}
}
// ignore: must_be_immutable
class ReusbaleRow extends StatelessWidget {
String title, value;
ReusbaleRow({Key? key, required this.title, required this.value})
: super(key: key);
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(title),
Text(value),
],
),
);
}
} ```

Flutter Execute Http request on startup using FutureBuilder not working

This is the homepage code of the app I'm currently developing and I have to get all data from API. Therefore I've come up _getLatest that gets the data from the URL which is a list of maps and the data goes into _latest. And I implemented the future builder based on Flutter: Execute a function on Startup - wait for HTTP response parser to extract image URL but things are not quite done.
First of all there are two blue underlines: 1. Future<String> _getLatest() async { says
This function has a return type of 'FutureOr', but doesn't end with a return statement. 2. builder: (BuildContext context, AsyncSnapshot<String> snapshot) { says This function has a return type of 'Widget', but doesn't end with a return statement.
And the main problem is the homepage is that snapshot.connectionState doesn't change to done state so it's loading data eternally. And I'm pretty sure it's because of the code not the URL, the API works fine.
import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:convert';
import 'package:kzstats/common/AppBar.dart';
import 'package:kzstats/common/Drawer.dart';
class Homepage extends StatefulWidget {
#override
_HomepageState createState() => _HomepageState();
}
class _HomepageState extends State<Homepage> {
final String currentPage = 'KZStats';
var _latest = [];
Future<String> _getLatest() async {
var url =
'https://kztimerglobal.com/api/v2.0/records/top/recent?stage=0&tickrate=128&modes_list_string=kz_timer&limit=3';
var httpClient = new HttpClient();
var result;
try {
var request = await httpClient.getUrl(Uri.parse(url));
var response = await request.close();
if (response.statusCode == HttpStatus.ok) {
var json = await response.transform(utf8.decoder).join();
var data = jsonDecode(json);
result = data;
} else {}
} catch (exception) {}
setState(() {
_latest = result;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: HomepageAppBar(currentPage),
drawer: HomepageDrawer(),
body: FutureBuilder<String>(
future: _getLatest(),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return ListView.builder(
itemCount: 3,
itemBuilder: (context, index) {
return new Card(
elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
),
color: Colors.white,
margin: const EdgeInsets.all(20),
child: Text('${_latest[index]}'),
);
},
);
} else if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
child: CircularProgressIndicator(),
width: 60,
height: 60,
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Loading data from API...'),
)
],
),
);
}
},
),
floatingActionButton: Builder(builder: (builderContext) {
return FloatingActionButton(onPressed: () {
_getLatest();
});
}),
);
}
}
First of all, you have done some wrong things,
if you are using FutureBuilder you can use a snapshot inside it so no need for _latest variable.
you can also use http package for easily requesting data.
inside your _getLatest() function you didn't returned the value and also it was not String.
also you can use Model class for easily assessing data after fetching json.
For your Problem my solution is
import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:convert';
import 'package:http/http.dart' as http;
class Homepage extends StatefulWidget {
#override
_HomepageState createState() => _HomepageState();
}
class _HomepageState extends State<Homepage> {
final String currentPage = 'KZStats';
Future<List<KzTimer>> _getLatest() async {
var url =
'https://kztimerglobal.com/api/v2.0/records/top/recent?stage=0&tickrate=128&modes_list_string=kz_timer&limit=3';
List<KzTimer> result;
try {
var response = await http.get(Uri.parse(url));
if (response.statusCode == HttpStatus.ok) {
result = kzTimerFromJson(response.body);
} else {
print('Something went wrong!');
}
} catch (exception) {}
return result;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<List<KzTimer>>(
future: _getLatest(),
builder: (BuildContext context, AsyncSnapshot<List<KzTimer>> snapshot) {
return snapshot.hasData ?
ListView.builder(
itemCount: 3,
itemBuilder: (context, index) {
return new Card(
elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
),
color: Colors.white,
margin: const EdgeInsets.all(20),
child: Text('${snapshot.data[index].playerName}'),
//_latest[index].playerName
);
},
) :
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
child: CircularProgressIndicator(),
width: 60,
height: 60,
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Loading data from API...'),
)
],
),
) ;
},
),
floatingActionButton: Builder(builder: (builderContext) {
return FloatingActionButton(onPressed: () {
_getLatest();
});
}),
);
}
}
Method to convert the response data to your model class data
List<KzTimer> kzTimerFromJson(String str) => List<KzTimer>.from(json.decode(str).map((x) => KzTimer.fromJson(x)));
Model class
class KzTimer {
KzTimer({
this.id,
this.steamid64,
this.playerName,
this.steamId,
this.serverId,
this.mapId,
this.stage,
this.mode,
this.tickrate,
this.time,
this.teleports,
this.createdOn,
this.updatedOn,
this.updatedBy,
this.place,
this.top100,
this.top100Overall,
this.serverName,
this.mapName,
this.points,
this.recordFilterId,
this.replayId,
});
int id;
String steamid64;
String playerName;
String steamId;
int serverId;
int mapId;
int stage;
String mode;
int tickrate;
double time;
int teleports;
DateTime createdOn;
DateTime updatedOn;
int updatedBy;
int place;
int top100;
int top100Overall;
String serverName;
String mapName;
int points;
int recordFilterId;
int replayId;
factory KzTimer.fromJson(Map<String, dynamic> json) => KzTimer(
id: json["id"],
steamid64: json["steamid64"],
playerName: json["player_name"],
steamId: json["steam_id"],
serverId: json["server_id"],
mapId: json["map_id"],
stage: json["stage"],
mode: json["mode"],
tickrate: json["tickrate"],
time: json["time"].toDouble(),
teleports: json["teleports"],
createdOn: DateTime.parse(json["created_on"]),
updatedOn: DateTime.parse(json["updated_on"]),
updatedBy: json["updated_by"],
place: json["place"],
top100: json["top_100"],
top100Overall: json["top_100_overall"],
serverName: json["server_name"],
mapName: json["map_name"],
points: json["points"],
recordFilterId: json["record_filter_id"],
replayId: json["replay_id"],
);
}
Change return type by: Future<void>. You are returning nothing.
You have an if and an else if but you still need the default case when both conditions are false.
import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:convert';
import 'package:kzstats/common/AppBar.dart';
import 'package:kzstats/common/Drawer.dart';
class Homepage extends StatefulWidget {
#override
_HomepageState createState() => _HomepageState();
}
class _HomepageState extends State<Homepage> {
final String currentPage = 'KZStats';
var _latest = [];
Future<String> _getLatest() async {
var url =
'https://kztimerglobal.com/api/v2.0/records/top/recent?stage=0&tickrate=128&modes_list_string=kz_timer&limit=3';
var httpClient = new HttpClient();
var result;
try {
var request = await httpClient.getUrl(Uri.parse(url));
var response = await request.close();
if (response.statusCode == HttpStatus.ok) {
var json = await response.transform(utf8.decoder).join();
var data = jsonDecode(json);
result = data;
} else {}
} catch (exception) {}
setState(() {
_latest = result;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: HomepageAppBar(currentPage),
drawer: HomepageDrawer(),
body: FutureBuilder<String>(
future: _getLatest(),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return ListView.builder(
itemCount: 3,
itemBuilder: (context, index) {
return new Card(
elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
),
color: Colors.white,
margin: const EdgeInsets.all(20),
child: Text('${_latest[index]}'),
);
},
);
} else if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
child: CircularProgressIndicator(),
width: 60,
height: 60,
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Loading data from API...'),
)
],
),
);
}
},
),
floatingActionButton: Builder(builder: (builderContext) {
return FloatingActionButton(onPressed: () =>
_getLatest;
}),
);
}
}
The Correct Version of Your Code

Pass data from future to another future in the same page

I'm new to the Flutter world and mobile app development and struggling with how I should pass data throughout my app. This is my code, How can I pass data from future to another future on the same page? these are my two futures and my class and my HomePage with the futurebuilders
help, please.
This is my future that returns the Location. From her I need to pass the Location id to the next future.
Future<Location> Lastlocation() async {
final prefs = await SharedPreferences.getInstance();
final key = 'token';
final value = prefs.get(key) ?? 0;
String myUrl = "$serverUrl/location/getlastlocation?token=" + value;
http.Response response = await http.get(
myUrl,
headers: {
'Accept': 'application/json',
//'Authorization': 'token $value'
},
);
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
return Location.fromJson(json.decode(response.body));
} else {
// then throw an exception.
throw Exception('Failed to load album');
}
}
**This is the second future that returns a List of weather that depends on location id from the first future *Lastlocation()
Future<List> Getweither(String ID) async {
final prefs = await SharedPreferences.getInstance();
final key = 'token';
final value = prefs.get(key) ?? 0;
String myUrl = "$serverUrl/dashbaord/Getweither/$ID?token=" + value;
http.Response response = await http.get(myUrl,
headers: {
'Accept': 'application/json',
});
print("myUrldevice :"+myUrl);
print("status :"+response.statusCode.toString());
return json.decode(response.body);
}
This is my class Location
// To parse this JSON data, do
//
// final location = locationFromJson(jsonString);
import 'dart:convert';
List<Location> locationFromJson(String str) => List<Location>.from(json.decode(str).map((x) => Location.fromJson(x)));
String locationToJson(List<Location> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Location {
Location({
this.automaticIrrigation,
this.coordinates,
this.createdDate,
this.sensorIds,
this.id,
this.siteName,
this.description,
this.v,
});
bool automaticIrrigation;
List<double> coordinates;
DateTime createdDate;
List<String> sensorIds;
String id;
String siteName;
String description;
int v;
factory Location.fromJson(Map<String, dynamic> json) => Location(
automaticIrrigation: json["AutomaticIrrigation"],
coordinates: List<double>.from(json["Coordinates"].map((x) => x.toDouble())),
createdDate: DateTime.parse(json["Created_date"]),
sensorIds: List<String>.from(json["Sensor_ids"].map((x) => x)),
id: json["_id"],
siteName: json["SiteName"],
description: json["Description"],
v: json["__v"],
);
Map<String, dynamic> toJson() => {
"AutomaticIrrigation": automaticIrrigation,
"Coordinates": List<dynamic>.from(coordinates.map((x) => x)),
"Created_date": createdDate.toIso8601String(),
"Sensor_ids": List<dynamic>.from(sensorIds.map((x) => x)),
"_id": id,
"SiteName": siteName,
"Description": description,
"__v": v,
};
}
and this is my homePage
import 'dart:convert';
import 'dart:developer';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sidebar_animation/Services/DataHelpers.dart';
import 'package:sidebar_animation/sidebar/sidebar_layout.dart';
import '../bloc.navigation_bloc/navigation_bloc.dart';
import 'package:sidebar_animation/constants.dart';
import 'package:flutter/gestures.dart';
import 'package:sidebar_animation/bloc.navigation_bloc/navigation_bloc.dart';
class HomePage extends StatelessWidget with NavigationStates {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
DatabaseHelper2 databaseHelper2 = new DatabaseHelper2();
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[100],
body: ListView(
FutureBuilder(
future: databaseHelper2.Getweither(location_id),
builder: (context,snapshot) {
if (snapshot.hasError)
{
print(snapshot.error);
print("there is problem !");
}
return snapshot.hasData
? ItemList(list: snapshot.data)
: Center(child: CircularProgressIndicator(
),
);
}
),
);
}
Widget _buildProgrammCard() {
return Container(
height: 90,
child:
Card(
semanticContainer: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
elevation: 4,
margin: EdgeInsets.fromLTRB(14, 0, 14, 14),
child:
FutureBuilder(
future: databaseHelper2.Lastlocation(),
builder: (context,snapshot) {
if (snapshot.hasError)
{
print(snapshot.error);
print("mochkla lenaa *");
}
return snapshot.hasData
? Text("Location :" +snapshot.data.siteName)
: Center(child: CircularProgressIndicator(
),
);
}
),
),
);
}
class ItemList extends StatelessWidget{
List list;
ItemList({this.list});
ScrollController _controller = new ScrollController();
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: list == null ? 0 : list.length,
scrollDirection: Axis.horizontal,
itemExtent: 190.0,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.fromLTRB(10, 0, 0, 14),
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
item.storyUrl,
),
fit: BoxFit.cover,
colorFilter: ColorFilter.mode(
Colors.black26,
BlendMode.darken,
),
),
borderRadius: BorderRadius.circular(10.0),
color: Colors.grey,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(10.0),
child: Text(
"temp :",
style: TextStyle(color: Colors.white),
),
),
Padding(
padding: EdgeInsets.only(left: 24),
child:
Text(
list[i]['Weither']['Temp'],
),
),
],
),
),
);
},
),
}
}
Finally, I need to get the location id from the first future that returns the Location to the second future Getweither(String ID) to get the weather of a specified location.
Just nest the two FutureBuilders, and pass the snapshot.data as a parameter of the second one.
Minimalistic example:
FutureBuilder(
future: databaseHelper2.Lastlocation(),
builder: (context, snapshot) {
if (snapshot.hasError) {
print(snapshot.error);
print("there is problem !");
}
return snapshot.hasData
? FutureBuilder(
future: databaseHelper2.Getweither(snapshot.data.id),
builder: (context, snapshot2) {...})
: Center(child: CircularProgressIndicator());
}
);