Flutter Return API Value to FutureBuilder Null - api

I want to get data from API and convert it List to show it to Mobile, but FutureBuilder always said my data is null. I already print my data it has the data. But when I return it to FutureBuilder it just null.
API Example
{
"success": true,
"data": {
"current_page": 1,
"data": [
{
"absence_date": "2021-02-09",
"time_in": "07:51:34",
"time_out": "17:14:28"
},
{
"absence_date": "2021-02-08",
"time_in": "07:53:56",
"time_out": "17:09:15"
},
{
"absence_date": "2021-02-05",
"time_in": "07:53:32",
"time_out": "17:17:31"
}
],
"last_page": 4
}
}
Attendance.dart -> Model
#JsonSerializable()
class Attendance {
#JsonKey()
List<dynamic> data;
#JsonKey()
int last_page;
Attendance();
factory Attendance.fromJson(Map<String, dynamic> json) => _$AttendanceFromJson(json);
Map<String, dynamic> toJson() => _$AttendanceToJson(this);
}
ListView.dart -> _fecthJobs
Widget build(BuildContext context) {
return FutureBuilder<List<Job>>(
future: _fetchJobs(),
builder: (context, snapshot) {
print(snapshot.data);
if (snapshot.hasData) {
List<Job> data = snapshot.data;
return _jobsListView(data);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
);
}
Future<List<Job>> _fetchJobs() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var email = prefs.getString('email');
await api.attendances(email).then((items) async {
if (items.success == true) {
Attendance att = Attendance.fromJson(items.data);
print(att.data);
return att.data.map((job) => new Job.fromJson(job)).toList();
}
}).catchError((e) {
print('Exception $e');
});
}
I print att.data, it has the data API, but when it in snapshot.data it say it's null

Related

Flutter Post API call

I'm working on flutter project, in which I'm calling an POST API. Its response is like
{
"_id": "5f61a39b8b7cf93550898b63",
"buildname": "ANT PC DORYLUS RZ320G",
"processor": "AMD Ryzen 3 3200G (4Core, 4Threads, Upto 4.0 Ghz)",
"motherboard": "MSI B450M PRO m2 Max",
"ram": "8GB ADATA XPG Gammix D30 DDR4 3000MHz",
"graphiccard": "Radeon Vega Graphics",
"ssd": "120GB ADATA/Crucial SATA SSD",
"hdd": "1 TB WD Blue SATA HDD 7200 RPM",
"psu": "Antec VP450P IN",
"cpucooler": "AMD STOCK COOLER",
"os": "30 Days Microsoft Windows 10 Home 64-Bit Trial",
"cpucase": "Antec NX200",
"price": "28437.00",
"createdAt": "2020-09-16T05:33:15.383Z",
"__v": 0
}
I wrote this following code but it showing me an error type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'PreBuildResponse'
Code:
Future<List<PreBuildResponse>> _fetchProduct() async {
final url = 'http://10.0.2.2:3000/prebuild/product';
final response = await http.post(
url,
body: {
'id' : "$productId"
}
);
if (response.statusCode == 200) {
List jsonResponse = json.decode(response.body);
return jsonResponse
.map((list) => new PreBuildResponse.fromJson(list))
.toList();
} else {
throw Exception('Failed to load data from API');
}
}
#override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: SingleChildScrollView(
child: FutureBuilder(
future: _fetchProduct(),
builder: (context, snapshot) {
if (snapshot.hasData) {
PreBuildResponse data = snapshot.data;
return Text(data.buildname);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
),
)
);
}
}
And find the model code here https://gist.github.com/vaandhare/3aa46c71369f012514cfafe4911cd11c
Future<PreBuildResponse> _fetchProduct() async {
final url = 'http://10.0.2.2:3000/prebuild/product';
final response = await http.post(
url,
body: {
'id' : "$productId"
}
);
if (response.statusCode == 200) {
return PreBuildResponse.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to load data from API');
}
}
you have to convert your JSON response to your model class.
there should have a fromJson method In the model class which you can use here while converting the JSON to your model class.
I have a Book Model class here so that you can refer it.
Future<List<Book>> getAllBook() async {
http.Response response = await http.get(
EndPoint.Book,
);
if (response.statusCode == 200) {
var parsed = jsonDecode(response.body);
var bookData = parsed['books'];
List<Book> data = bookData.map<Book>((e) => Book.fromJson(e)).toList();
print(data);
return data;
}
}

Flutter : Future Builder receive null from calsses

I am trying to make live score app ,I have a model created by quiqtype.io from json :
import 'dart:convert';
Live liveFromJson(String str) => Live.fromJson(json.decode(str));
String liveToJson(Live data) => json.encode(data.toJson());
class Live {
Live({
this.success,
this.data,
});
bool success;
Data data;
factory Live.fromJson(Map<String, dynamic> json) => Live(
success: json["success"],
data: Data.fromJson(json["data"]),
);
Map<String, dynamic> toJson() => {
"success": success,
"data": data.toJson(),
};
}
class Data {
Data({
this.fixtures,
this.nextPage,
this.prevPage,
});
List<Fixture> fixtures;
String nextPage;
bool prevPage;
factory Data.fromJson(Map<String, dynamic> json) => Data(
fixtures: List<Fixture>.from(
json["fixtures"].map((x) => Fixture.fromJson(x))),
nextPage: json["next_page"],
prevPage: json["prev_page"],
);
Map<String, dynamic> toJson() => {
"fixtures": List<dynamic>.from(fixtures.map((x) => x.toJson())),
"next_page": nextPage,
"prev_page": prevPage,
};
}
class Fixture {
Fixture({
this.id,
this.date,
this.time,
this.round,
this.homeName,
this.awayName,
this.location,
this.leagueId,
this.competitionId,
this.homeId,
this.awayId,
this.competition,
this.league,
});
String id;
DateTime date;
String time;
String round;
String homeName;
String awayName;
String location;
String leagueId;
String competitionId;
String homeId;
String awayId;
Competition competition;
League league;
factory Fixture.fromJson(Map<String, dynamic> json) => Fixture(
id: json["id"],
date: DateTime.parse(json["date"]),
time: json["time"],
round: json["round"],
homeName: json["home_name"],
awayName: json["away_name"],
location: json["location"],
leagueId: json["league_id"],
competitionId: json["competition_id"],
homeId: json["home_id"],
awayId: json["away_id"],
competition: Competition.fromJson(json["competition"]),
league: json["league"] == null ? null : League.fromJson(json["league"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"date":
"${date.year.toString().padLeft(4, '0')}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}",
"time": time,
"round": round,
"home_name": homeName,
"away_name": awayName,
"location": location,
"league_id": leagueId,
"competition_id": competitionId,
"home_id": homeId,
"away_id": awayId,
"competition": competition.toJson(),
"league": league == null ? null : league.toJson(),
};
}
class Competition {
Competition({
this.id,
this.name,
});
String id;
String name;
factory Competition.fromJson(Map<String, dynamic> json) => Competition(
id: json["id"],
name: json["name"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
};
}
class League {
League({
this.id,
this.name,
this.countryId,
});
String id;
String name;
String countryId;
factory League.fromJson(Map<String, dynamic> json) => League(
id: json["id"],
name: json["name"],
countryId: json["country_id"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"country_id": countryId,
};
}
the i create API service class :
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:myexpect/models/match_fixture.dart';
class Api {
Future<Live> get_fixture() async {
var fixture_model = null;
var client = http.Client();
try {
var url =
'https://livescore-api.com/api-client/fixtures/matches.json?key=xxxxxxC&secret=yyyyy&page=1';
var response = await client.get(url);
if (response.statusCode == 200) {
var jsonString = response.body;
var jsonMap = json.decode(jsonString);
fixture_model = Live.fromJson(jsonMap);
print(jsonMap ): //--- printed the list in console successfully
}
} catch (Exception) {
return fixture_model;
}
}
}
I am now trying to view this data's in future building in this page :
import 'package:flutter/material.dart';
import '../services/live_score_api.dart';
import '../models/match_fixture.dart';
class LiveScore extends StatefulWidget {
#override
_LiveScoreState createState() => _LiveScoreState();
}
class _LiveScoreState extends State<LiveScore> {
Future<Live> _fixtures;
#override
void initState() {
_fixtures = Api().get_fixture();
super.initState();
}
#override
Widget build(BuildContext context) {
return FutureBuilder<Live>(
future: _fixtures,
builder: (ctx, snapshot) {
if (snapshot.connectionState == ConnectionState.none ||
snapshot.connectionState == ConnectionState.waiting ||
snapshot.connectionState == ConnectionState.active ||
snapshot.data == null) {
return Container(
child: Text('Loading.......'),
);
} else {
return ListView.builder(
itemCount: snapshot.data.data.fixtures.length,
itemBuilder: (ctx, index) {
var data = snapshot.data.data.fixtures[index];
return Text(data.time);
});
}
},
);
}
}
when i load this page ,the list of data printed successfully at console but the future builder receive null ,therefore just the text 'Loading ...' is viewed ,and no error no exception found
You want to implement your future builder like this:
return FutureBuilder<Live>(
future: _fixtures,
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
case ConnectionState.active:
// Loading widget
return CircularProgressIndicator();
case ConnectionState.done:
if (snapshot.hasError) {
// return error widget
}
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.data.fixtures.length,
itemBuilder: (ctx, index) {
var data = snapshot.data.data.fixtures[index];
return Text(data.time);
});
}
}
},
);
On top of that, you catch the exception, but you don't throw an exception. So it will not throw an error. Which is kinda what you want to know in a future builder. I recommend throwing an exception.
I found my error ,is here :
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:myexpect/models/match_fixture.dart';
class Api {
Future<Live> get_fixture() async {
var fixture_model = null;
var client = http.Client();
try {
var url =
'https://livescore-api.com/api-client/fixtures/matches.json?key=xxxxxxC&secret=yyyyy&page=1';
var response = await client.get(url);
if (response.statusCode == 200) {
var jsonString = response.body;
var jsonMap = json.decode(jsonString);
fixture_model = Live.fromJson(jsonMap);
print(jsonMap ): //--- printed the list in console successfully
}
} catch (Exception) {
return fixture_model;
}
}
}
I forgot to return the list outside catch exception ,after i added return it is fixed :
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:myexpect/models/match_fixture.dart';
class Api {
Future<Live> get_fixture() async {
var fixture_model = null;
var client = http.Client();
try {
var url =
'https://livescore-api.com/api-client/fixtures/matches.json?key=xxxxxxC&secret=yyyyy&page=1';
var response = await client.get(url);
if (response.statusCode == 200) {
var jsonString = response.body;
var jsonMap = json.decode(jsonString);
fixture_model = Live.fromJson(jsonMap);
print(jsonMap ): //--- printed the list in console successfully
}
} catch (Exception) {
return fixture_model;
}
return fixture_model; //------------I added this line that i forgot :)
}
}

_TypeError in call api flutter

Good afternoon, I am making a call to my api to bring the businesses that I have registered.
This is my model
class Shops{
Shops({
this.id,
this.name,
this.phone,
this.merchantType,
this.address,
this.city,
this.distance,
this.logo,
});
String id;
String name;
String phone;
String merchantType;
String address;
String city;
double distance;
String logo;
factory Shops.fromJson(Map<String, dynamic> json){
return Shops(
id: json["_id"],
name : json["name"],
phone : json["phone"],
merchantType : json["merchantType"],
address : json["address"],
city : json["city"],
distance : json["distance"].toDouble(),
logo : json["logo"],
);
}
}
Here I make the call
Future<Shops> getShops(var userLatitude, var userLongitude) async {
final response =
await http.get('https://dry-plateau-30024.herokuapp.com/v1/front/merchants?lat=$userLatitude&lng=$userLongitude');
if (response.statusCode == 200) {
return Shops.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to load Shops');
}
}
so I show the results
FutureBuilder<Shops>(
future:
getShops(services.userLatitude, services.userLongitude),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.name);
} else if (snapshot.hasError) {
return Information(
title: 'No results found',
subtitle: 'It seems there is nothing in your area',
img: 'assets/nada.png',
);
} else {
return CircularProgressIndicator();
}
},
)
This returns me the following error
_TypeError (type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>'
I am evolving with the framework and the dart language, I am presented with these errors that perhaps for you are a newbie. I would appreciate a little help
Using the new link for the JSON you have given. Since it is a list we will have to cast it to a list and map through it. Before you were just returning one instance of ShopsFuture<Shops> instead of Future<List<Shops>>
class _CompaniesState extends State<Companies> {
Future<List<Shops>> getShops(var userLatitude, var userLongitude) async {
final response =
await http.get("https://dry-plateau-30024.herokuapp.com/v1/front/merchants?lat=-27.4885846&lng=-58.9509858");
if (response.statusCode == 200) {
// typecasting it into a list
var jsonData = json.decode(response.body) as List;
// Map through it and return it
return jsonData.map((shop) => Shops.fromJson(shop)).toList();
} else {
throw Exception('Failed to load Shops');
}
}
#override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder<List<Shops>>(
future: getShops(12, 20),
builder: (context, snapshot) {
if (snapshot.hasData) {
// Accessing the first map from the list and getting the name key
return Text(snapshot.data[0].name);
} else if (snapshot.hasError) {
return null;
return Information(
title: 'No results found',
subtitle: 'It seems there is nothing in your area',
img: 'assets/nada.png',
);
} else {
return CircularProgressIndicator();
}
},
));
}
}

How to use CoinMarketCap API in flutter

I'm following a tutorial for an app that displays cryptocurrency prices and I have trouble with the new API. The code below is just from the tutorial and the tutor is using the old coinmarketcap API. Coinmarketcap has migrated to a new one and you need to sign up to get a free API key. Documentation for new API: https://coinmarketcap.com/api/documentation/v1.
I think I need to change _apiURL to https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?start=1&limit=5000&convert=USD and somehow use the APIKey. Does anyone have a solution? Still kinda new to flutter and API's so i'm sorry if the question is hard to answer.
Future<void> getCryptoPrices() async {
//async to use await, which suspends the current function, while it does other stuff and resumes when data ready
print('getting crypto prices'); //print
String _apiURL =
"https://api.coinmarketcap.com/v1/ticker/"; //url to get data
setState(() {
this._loading = true; //before calling the api, set the loading to true
});
http.Response response = await http.get(_apiURL); //waits for response
setState(() {
this._cryptoList =
jsonDecode(response.body); //sets the state of our widget
this._loading = false; //set the loading to false after we get a response
print(_cryptoList); //prints the list
});
return; }
You can copy paste run full code below and replace your-key before run
You can put API key in headers and parse json response with payloadFromJson and display with FutureBuilder
You can see Payload class definition in full code
Future<Payload> getCryptoPrices() async {
var response = await http.get(
"https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?start=1&limit=5000&convert=USD",
headers: {
'X-CMC_PRO_API_KEY': 'your-key',
"Accept": "application/json",
});
if (response.statusCode == 200) {
return payloadFromJson(response.body);
}
}
working demo
full code
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
Payload payloadFromJson(String str) => Payload.fromJson(json.decode(str));
String payloadToJson(Payload data) => json.encode(data.toJson());
class Payload {
Payload({
this.status,
this.data,
});
Status status;
List<Datum> data;
factory Payload.fromJson(Map<String, dynamic> json) => Payload(
status: Status.fromJson(json["status"]),
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status.toJson(),
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
Datum({
this.id,
this.name,
this.symbol,
this.slug,
this.numMarketPairs,
this.dateAdded,
this.tags,
this.maxSupply,
this.circulatingSupply,
this.totalSupply,
this.platform,
this.cmcRank,
this.lastUpdated,
this.quote,
});
int id;
String name;
String symbol;
String slug;
int numMarketPairs;
DateTime dateAdded;
List<Tag> tags;
double maxSupply;
double circulatingSupply;
double totalSupply;
Platform platform;
int cmcRank;
DateTime lastUpdated;
Quote quote;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
name: json["name"],
symbol: json["symbol"],
slug: json["slug"],
numMarketPairs: json["num_market_pairs"],
dateAdded: DateTime.parse(json["date_added"]),
tags: List<Tag>.from(json["tags"].map((x) => tagValues.map[x])),
maxSupply:
json["max_supply"] == null ? null : json["max_supply"].toDouble(),
circulatingSupply: json["circulating_supply"] == null
? null
: json["circulating_supply"].toDouble(),
totalSupply: json["total_supply"] == null
? null
: json["total_supply"].toDouble(),
platform: json["platform"] == null
? null
: Platform.fromJson(json["platform"]),
cmcRank: json["cmc_rank"],
lastUpdated: DateTime.parse(json["last_updated"]),
quote: Quote.fromJson(json["quote"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"symbol": symbol,
"slug": slug,
"num_market_pairs": numMarketPairs,
"date_added": dateAdded.toIso8601String(),
"tags": List<dynamic>.from(tags.map((x) => tagValues.reverse[x])),
"max_supply": maxSupply == null ? null : maxSupply,
"circulating_supply":
circulatingSupply == null ? null : circulatingSupply,
"total_supply": totalSupply == null ? null : totalSupply,
"platform": platform == null ? null : platform.toJson(),
"cmc_rank": cmcRank,
"last_updated": lastUpdated.toIso8601String(),
"quote": quote.toJson(),
};
}
class Platform {
Platform({
this.id,
this.name,
this.symbol,
this.slug,
this.tokenAddress,
});
int id;
Name name;
Symbol symbol;
Slug slug;
String tokenAddress;
factory Platform.fromJson(Map<String, dynamic> json) => Platform(
id: json["id"],
name: nameValues.map[json["name"]],
symbol: symbolValues.map[json["symbol"]],
slug: slugValues.map[json["slug"]],
tokenAddress: json["token_address"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": nameValues.reverse[name],
"symbol": symbolValues.reverse[symbol],
"slug": slugValues.reverse[slug],
"token_address": tokenAddress,
};
}
enum Name {
ETHEREUM,
TRON,
OMNI,
RSK_SMART_BITCOIN,
BINANCE_COIN,
STELLAR,
NEO,
V_SYSTEMS,
ARDOR,
QTUM,
XRP,
WAVES,
ONTOLOGY,
EOS,
NEBULAS,
NEM,
BIT_SHARES,
BITCOIN_CASH,
INT_CHAIN,
COSMOS,
UBIQ,
VE_CHAIN,
NU_BITS,
PIVX,
COUNTERPARTY,
KOMODO,
ICON,
GX_CHAIN,
VITE,
WANCHAIN,
IOST,
TRUE_CHAIN,
ETHEREUM_CLASSIC
}
final nameValues = EnumValues({
"Ardor": Name.ARDOR,
"Binance Coin": Name.BINANCE_COIN,
"Bitcoin Cash": Name.BITCOIN_CASH,
"BitShares": Name.BIT_SHARES,
"Cosmos": Name.COSMOS,
"Counterparty": Name.COUNTERPARTY,
"EOS": Name.EOS,
"Ethereum": Name.ETHEREUM,
"Ethereum Classic": Name.ETHEREUM_CLASSIC,
"GXChain": Name.GX_CHAIN,
"ICON": Name.ICON,
"INT Chain": Name.INT_CHAIN,
"IOST": Name.IOST,
"Komodo": Name.KOMODO,
"Nebulas": Name.NEBULAS,
"NEM": Name.NEM,
"Neo": Name.NEO,
"NuBits": Name.NU_BITS,
"Omni": Name.OMNI,
"Ontology": Name.ONTOLOGY,
"PIVX": Name.PIVX,
"Qtum": Name.QTUM,
"RSK Smart Bitcoin": Name.RSK_SMART_BITCOIN,
"Stellar": Name.STELLAR,
"TRON": Name.TRON,
"TrueChain": Name.TRUE_CHAIN,
"Ubiq": Name.UBIQ,
"VeChain": Name.VE_CHAIN,
"VITE": Name.VITE,
"v.systems": Name.V_SYSTEMS,
"Wanchain": Name.WANCHAIN,
"Waves": Name.WAVES,
"XRP": Name.XRP
});
enum Slug {
ETHEREUM,
TRON,
OMNI,
RSK_SMART_BITCOIN,
BINANCE_COIN,
STELLAR,
NEO,
V_SYSTEMS,
ARDOR,
QTUM,
XRP,
WAVES,
ONTOLOGY,
EOS,
NEBULAS_TOKEN,
NEM,
BITSHARES,
BITCOIN_CASH,
INT_CHAIN,
COSMOS,
UBIQ,
VECHAIN,
NUBITS,
PIVX,
COUNTERPARTY,
KOMODO,
ICON,
GXCHAIN,
VITE,
WANCHAIN,
IOSTOKEN,
TRUECHAIN,
ETHEREUM_CLASSIC
}
final slugValues = EnumValues({
"ardor": Slug.ARDOR,
"binance-coin": Slug.BINANCE_COIN,
"bitcoin-cash": Slug.BITCOIN_CASH,
"bitshares": Slug.BITSHARES,
"cosmos": Slug.COSMOS,
"counterparty": Slug.COUNTERPARTY,
"eos": Slug.EOS,
"ethereum": Slug.ETHEREUM,
"ethereum-classic": Slug.ETHEREUM_CLASSIC,
"gxchain": Slug.GXCHAIN,
"icon": Slug.ICON,
"int-chain": Slug.INT_CHAIN,
"iostoken": Slug.IOSTOKEN,
"komodo": Slug.KOMODO,
"nebulas-token": Slug.NEBULAS_TOKEN,
"nem": Slug.NEM,
"neo": Slug.NEO,
"nubits": Slug.NUBITS,
"omni": Slug.OMNI,
"ontology": Slug.ONTOLOGY,
"pivx": Slug.PIVX,
"qtum": Slug.QTUM,
"rsk-smart-bitcoin": Slug.RSK_SMART_BITCOIN,
"stellar": Slug.STELLAR,
"tron": Slug.TRON,
"truechain": Slug.TRUECHAIN,
"ubiq": Slug.UBIQ,
"vechain": Slug.VECHAIN,
"vite": Slug.VITE,
"v-systems": Slug.V_SYSTEMS,
"wanchain": Slug.WANCHAIN,
"waves": Slug.WAVES,
"xrp": Slug.XRP
});
enum Symbol {
ETH,
TRX,
OMNI,
RBTC,
BNB,
XLM,
NEO,
VSYS,
ARDR,
QTUM,
XRP,
WAVES,
ONT,
EOS,
NAS,
XEM,
BTS,
BCH,
INT,
ATOM,
UBQ,
VET,
USNBT,
PIVX,
XCP,
KMD,
ICX,
GXC,
VITE,
WAN,
IOST,
TRUE,
ETC
}
final symbolValues = EnumValues({
"ARDR": Symbol.ARDR,
"ATOM": Symbol.ATOM,
"BCH": Symbol.BCH,
"BNB": Symbol.BNB,
"BTS": Symbol.BTS,
"EOS": Symbol.EOS,
"ETC": Symbol.ETC,
"ETH": Symbol.ETH,
"GXC": Symbol.GXC,
"ICX": Symbol.ICX,
"INT": Symbol.INT,
"IOST": Symbol.IOST,
"KMD": Symbol.KMD,
"NAS": Symbol.NAS,
"NEO": Symbol.NEO,
"OMNI": Symbol.OMNI,
"ONT": Symbol.ONT,
"PIVX": Symbol.PIVX,
"QTUM": Symbol.QTUM,
"RBTC": Symbol.RBTC,
"TRUE": Symbol.TRUE,
"TRX": Symbol.TRX,
"UBQ": Symbol.UBQ,
"USNBT": Symbol.USNBT,
"VET": Symbol.VET,
"VITE": Symbol.VITE,
"VSYS": Symbol.VSYS,
"WAN": Symbol.WAN,
"WAVES": Symbol.WAVES,
"XCP": Symbol.XCP,
"XEM": Symbol.XEM,
"XLM": Symbol.XLM,
"XRP": Symbol.XRP
});
class Quote {
Quote({
this.usd,
});
Usd usd;
factory Quote.fromJson(Map<String, dynamic> json) => Quote(
usd: Usd.fromJson(json["USD"]),
);
Map<String, dynamic> toJson() => {
"USD": usd.toJson(),
};
}
class Usd {
Usd({
this.price,
this.volume24H,
this.percentChange1H,
this.percentChange24H,
this.percentChange7D,
this.marketCap,
this.lastUpdated,
});
double price;
double volume24H;
double percentChange1H;
double percentChange24H;
double percentChange7D;
double marketCap;
DateTime lastUpdated;
factory Usd.fromJson(Map<String, dynamic> json) => Usd(
price: json["price"] == null ? null : json["price"].toDouble(),
volume24H:
json["volume_24h"] == null ? null : json["volume_24h"].toDouble(),
percentChange1H: json["percent_change_1h"] == null
? null
: json["percent_change_1h"].toDouble(),
percentChange24H: json["percent_change_24h"] == null
? null
: json["percent_change_24h"].toDouble(),
percentChange7D: json["percent_change_7d"] == null
? null
: json["percent_change_7d"].toDouble(),
marketCap:
json["market_cap"] == null ? null : json["market_cap"].toDouble(),
lastUpdated: DateTime.parse(json["last_updated"]),
);
Map<String, dynamic> toJson() => {
"price": price == null ? null : price,
"volume_24h": volume24H == null ? null : volume24H,
"percent_change_1h": percentChange1H == null ? null : percentChange1H,
"percent_change_24h":
percentChange24H == null ? null : percentChange24H,
"percent_change_7d": percentChange7D == null ? null : percentChange7D,
"market_cap": marketCap == null ? null : marketCap,
"last_updated": lastUpdated.toIso8601String(),
};
}
enum Tag { MINEABLE }
final tagValues = EnumValues({"mineable": Tag.MINEABLE});
class Status {
Status({
this.timestamp,
this.errorCode,
this.errorMessage,
this.elapsed,
this.creditCount,
this.notice,
});
DateTime timestamp;
int errorCode;
dynamic errorMessage;
int elapsed;
int creditCount;
dynamic notice;
factory Status.fromJson(Map<String, dynamic> json) => Status(
timestamp: DateTime.parse(json["timestamp"]),
errorCode: json["error_code"],
errorMessage: json["error_message"],
elapsed: json["elapsed"],
creditCount: json["credit_count"],
notice: json["notice"],
);
Map<String, dynamic> toJson() => {
"timestamp": timestamp.toIso8601String(),
"error_code": errorCode,
"error_message": errorMessage,
"elapsed": elapsed,
"credit_count": creditCount,
"notice": notice,
};
}
class EnumValues<T> {
Map<String, T> map;
Map<T, String> reverseMap;
EnumValues(this.map);
Map<T, String> get reverse {
if (reverseMap == null) {
reverseMap = map.map((k, v) => new MapEntry(v, k));
}
return reverseMap;
}
}
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;
Future<Payload> _future;
Future<Payload> getCryptoPrices() async {
var response = await http.get(
"https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?start=1&limit=5000&convert=USD",
headers: {
'X-CMC_PRO_API_KEY': 'your-key',
"Accept": "application/json",
});
if (response.statusCode == 200) {
return payloadFromJson(response.body);
}
}
#override
void initState() {
// TODO: implement initState
super.initState();
_future = getCryptoPrices();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FutureBuilder(
future: _future,
builder: (context, AsyncSnapshot<Payload> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('none');
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
case ConnectionState.active:
return Text('');
case ConnectionState.done:
if (snapshot.hasError) {
return Text(
'${snapshot.error}',
style: TextStyle(color: Colors.red),
);
} else {
return ListView.builder(
itemCount: snapshot.data.data.length,
itemBuilder: (context, index) {
return Card(
elevation: 6.0,
child: Padding(
padding: const EdgeInsets.only(
top: 6.0,
bottom: 6.0,
left: 8.0,
right: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(snapshot.data.data[index].name),
Spacer(),
Text(snapshot.data.data[index].lastUpdated
.toIso8601String()),
Spacer(),
Text(
snapshot.data.data[index].quote.usd.price
.toString(),
),
],
),
));
});
}
}
}));
}
}

Flutter FutureBuilder returning null data

I'm new to Flutter and Dart, and I'm trying to write a application to test it.
I have an api that I'm getting the data for the app, and was trying to use the StatefulWidget and the FutureBuilder.
When I run the method to call the api I have the results (used print() to test it), but when I get the data from loadData method it retrives null.
So loadData prints the data, initState and FutureBuilder the data returns null. What am I missing here.
I have added the service and the models used for the request... hope it help.
Future<CoachesModelRes> loadData(Profile _profile) async {
await getPost(_profile.getToken()).then((response) {
if (response.statusCode == 200) {
CoachesModelRes coaches = coachesModel.postFromJson(response.body);
if (coaches.count > 0) {
print(coaches.count);
print(coaches.coaches[0].description);
return coaches;
} else {
return null;
}
} else {
String code = response.statusCode.toString();
return null;
}
}).catchError((error) {
print(error.toString());
return null;
});
}
#override
void initState() {
super.initState();
print(widget.profile.getToken());
data = loadData(widget.profile);
data.then((data_) async {
var cenas = data_.count;
print("asdasd $cenas");
});
}
Future<CoachesModelRes> data;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: appWhiteColor,
appBar: applicationBar(),
drawer: adminDrawer(widget.profile, AdminDrawerListEnum.coaches, context),
body: FutureBuilder<CoachesModelRes>(
future: data,
builder: (context, snapshot) {
//print(snapshot.data.count.toString());
if (snapshot.hasData) {
return Text("nop");
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return Text("nop");
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
);
}
Future<http.Response> getPost(String token) async {
final response = await http.get(new Uri.http("$apiUrl", "$coachesEndPoint"),
headers: {
HttpHeaders.contentTypeHeader: 'application/json',
HttpHeaders.authorizationHeader : 'Bearer $token'
},
);
return response;
}
CoachesModelRes postFromJson(String str) => CoachesModelRes.fromJson(json.decode(str));
class CoachesModelRes {
int count;
List<CoachModelRes> coaches;
CoachesModelRes({
this.count,
this.coaches,
});
factory CoachesModelRes.fromJson(Map<String, dynamic> json) => new CoachesModelRes(
count: json["count"],
coaches: (json["coaches"] as List).map((i) => CoachModelRes.fromJson(i)).toList(),
);
}
CoachModelRes postFromJson(String str) => CoachModelRes.fromJson(json.decode(str));
class CoachModelRes {
String id;
String firstName;
String lastName;
String description;
String username;
String notes;
List<String> roles;
CoachModelRes({
this.id,
this.firstName,
this.lastName,
this.description,
this.username,
this.notes,
this.roles,
});
factory CoachModelRes.fromJson(Map<String, dynamic> json) => new CoachModelRes(
id: json["id"],
firstName: json["firstName"],
lastName: json["lastName"],
description: json["description"],
username: json["username"],
notes: json["notes"],
roles: new List<String>.from(json["roles"]),
);
}
Future<CoachesModelRes> loadData(Profile _profile) async {
final response = await getPost(_profile.getToken());
try{if (response.statusCode == 200) {
CoachesModelRes coaches = coachesModel.postFromJson(response.body);
if (coaches.count > 0) {
print(coaches.count);
print(coaches.coaches[0].description);
return coaches;
} else {
return null;
}
} else {
String code = response.statusCode.toString();
return null;
}}catch(e){
return null ;
}
}
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: appWhiteColor,
appBar: applicationBar(),
drawer: adminDrawer(widget.profile, AdminDrawerListEnum.coaches, context),
body: FutureBuilder<CoachesModelRes>(
future: loadData(widget.profile),
builder: (context, snapshot) {
//print(snapshot.data.count.toString());
if (snapshot.hasData) {
return Text("nop");
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return Text("nop");
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
);
}
The issue here is that the return statement should be at the end of the method.
Because the getPost will return data to the loadData.
And when the getPost finishes the loadData will return data to the method that invoked him.
In my case, the loadData is not returning anything so the snapshot in the FutureBuilder it's always null.
It's logic that it is this way now, but at the time I could not figure it out :\
Future<CoachesModelRes> loadData(Profile _profile) async {
// So I need to create a variable to return
CoachesModelRes response;
//-----
await getPost(_profile.getToken()).then((response) {
if (response.statusCode == 200) {
CoachesModelRes coaches = coachesModel.postFromJson(response.body);
if (coaches.count > 0) {
print(coaches.count);
print(coaches.coaches[0].description);
// Set the variable value
response = coaches;
//-----
} else {
// Set the variable value
response = null;
//-----
}
} else {
String code = response.statusCode.toString();
// Set the variable value
response = null;
//-----
}
}).catchError((error) {
print(error.toString());
// Set the variable value
response = null;
//-----
});
// And at the end return the response variable
return response;
//-----
}