I wasn't get any data from fake Api : https://jsonplaceholder.typicode.com/users to my flutter App. Can anyone please give me piece of advise why or how I can get those data on my app. For creating the Model file using https://app.quicktype.io/.
JsonModel File:
import 'dart:convert';
List<JsonModel> jsonModelFromJson(String str) =>
List<JsonModel>.from(json.decode(str).map((x) => JsonModel.fromJson(x)));
String jsonModelToJson(List<JsonModel> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class JsonModel {
JsonModel({
this.id,
this.name,
this.username,
this.email,
this.address,
this.phone,
this.website,
this.company,
});
int? id;
String? name;
String? username;
String? email;
Address? address;
String? phone;
String? website;
Company? company;
factory JsonModel.fromJson(Map<String, dynamic> json) => JsonModel(
id: json["id"],
name: json["name"],
username: json["username"],
email: json["email"],
address: Address.fromJson(json["address"]),
phone: json["phone"],
website: json["website"],
company: Company.fromJson(json["company"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"username": username,
"email": email,
"address": address?.toJson(),
"phone": phone,
"website": website,
"company": company?.toJson(),
};
}
class Address {
Address({
this.street,
this.suite,
this.city,
this.zipcode,
this.geo,
});
String? street;
String? suite;
String? city;
String? zipcode;
Geo? geo;
factory Address.fromJson(Map<String, dynamic> json) => Address(
street: json["street"],
suite: json["suite"],
city: json["city"],
zipcode: json["zipcode"],
geo: Geo.fromJson(json["geo"]),
);
Map<String, dynamic> toJson() => {
"street": street,
"suite": suite,
"city": city,
"zipcode": zipcode,
"geo": geo?.toJson(),
};
}
class Geo {
Geo({
this.lat,
this.lng,
});
String? lat;
String? lng;
factory Geo.fromJson(Map<String, dynamic> json) => Geo(
lat: json["lat"],
lng: json["lng"],
);
Map<String, dynamic> toJson() => {
"lat": lat,
"lng": lng,
};
}
class Company {
Company({
this.name,
this.catchPhrase,
this.bs,
});
String? name;
String? catchPhrase;
String? bs;
factory Company.fromJson(Map<String, dynamic> json) => Company(
name: json["name"],
catchPhrase: json["catchPhrase"],
bs: json["bs"],
);
Map<String, dynamic> toJson() => {
"name": name,
"catchPhrase": catchPhrase,
"bs": bs,
};
}
Service or JsonApi File:
import 'dart:convert';
import 'package:flutter_learning_from_pageview/Model/JsonModel.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;
class JsonApi {
bool loading = true;
var json_Data;
Future<JsonModel> getJsonData() async {
var client = http.Client();
String uri = "https://jsonplaceholder.typicode.com/users";
var response = await client.get(Uri.parse(uri));
var jsonModel = null;
try {
if (response.statusCode == 200) {
var decode = json.decode(response.body);
jsonModel = JsonModel.fromJson(decode);
print(jsonModel);
} else {
throw Exception("falied to load");
}
} catch (Exception) {
return jsonModel;
}
return jsonModel;
}
}
Try to call it but As progress bar not closed it mean I didn't get the data
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_learning_from_pageview/Model/JsonModel.dart';
import 'package:flutter_learning_from_pageview/Service/JsonApi.dart';
class JsonData extends StatefulWidget {
const JsonData({Key? key}) : super(key: key);
#override
_JsonDataState createState() => _JsonDataState();
}
class _JsonDataState extends State<JsonData> {
bool loading = true;
Future<JsonModel>? _jsonModel;
#override
void initState() {
_jsonModel = JsonApi().getJsonData();
super.initState();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: FutureBuilder(
future: _jsonModel,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
//itemCount: json_Data == null ? 0 : json_Data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(""),
//subtitle: Text(json_Data[index]["body"]),
);
});
} else {
return Center(child: CircularProgressIndicator());
}
},
),
),
);
}
}
You made some mistake so try to change it to like this. you are trying to parse list of data with just a single element.
class JsonApi {
Future<List<JsonModel>> getJsonData() async {
var client = http.Client();
String uri = "https://jsonplaceholder.typicode.com/users";
var response = await client.get(Uri.parse(uri));
if (response.statusCode == 200) {
return jsonModelFromJson(response.body);
} else {
throw Exception("falied to load");
}
}
}
Then try this code
late final Future<List<JsonModel>> _futureData;
apiCalling() {
_futureData = JsonApi().getJsonData();
}
#override
void initState() {
apiCalling();
super.initState();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: FutureBuilder(
future: _futureData,
builder: (context, AsyncSnapshot<List<JsonModel>> snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.length,
//itemCount: json_Data == null ? 0 : json_Data.length,
itemBuilder: (context, index) {
return ListTile(
onTap: () {
setState(() {});
},
title: Text(snapshot.data![index].name!),
//subtitle: Text(json_Data[index]["body"]),
);
});
} else {
return Center(child: CircularProgressIndicator());
}
},
),
),
);
}
from init state you have to change like this:
#override
void initState() {
callApi();
super.initState();
}
void callApi() async {
_jsonModel = await JsonApi().getJsonData();
}
as you are not calling that with await so, it has no data
I found your issue. You trying to fetch data in wrong jsonModel.
Remove this code
var decode = json.decode(response.body);
jsonModel = JsonModel.fromJson(decode);
Use this Instead
jsonModel = jsonModelFromJson(response.body);
Your Api data is in Array format and you are trying to store in Class format.
Try below code hope its help to you.
Your API Call:
Future<List<dynamic>> getJobsData() async {
String url = 'https://jsonplaceholder.typicode.com/users';
var response = await http.get(Uri.parse(url), headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
});
return json.decode(response.body);
}
Your Widget:
Center(
child: FutureBuilder<List<dynamic>>(
future: getJobsData(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ListView.builder(
shrinkWrap: true,
physics:const NeverScrollableScrollPhysics(),
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
var id = snapshot.data![index]['id'];
var name = snapshot.data![index]['name'];
var username = snapshot.data![index]['username'];
var email = snapshot.data![index]['email'];
var phone = snapshot.data![index]['phone'];
return Card(
shape: RoundedRectangleBorder(
side: BorderSide(
color: Colors.green.shade300,
),
borderRadius: BorderRadius.circular(15.0),
),
child: ListTile(
leading: Text(id.toString()),
title: Text(name),
subtitle: Text(
username + '\n' + email + '\n' + phone.toString(),
),
),
);
},
),
);
}
return const CircularProgressIndicator();
},
),
),
Refer my answer here and here for get data from json API
Your Result Screen->
Make sure response.body is returning data.
Avoid using ? in futures, otherwise snapshot could be empty the whole time when body is null. The ui will always show loading.
To make your code look more simple:
Inside statefull widget:
late final Future<List<Data>> _futureData;
And in your initState:
#override
void initState(){
_futureData = provider.loadFutureData();
super.initState();
}
Or if you don't are using provider:
#override
void initState(){
_futureData = loadDataFromFunction();
super.initState();
}
Related
this is my model:
// To parse this JSON data, do
//
// final economylistXml = economylistXmlFromJson(jsonString);
import 'dart:convert';
EconomylistXml economylistXmlFromJson(String str) => EconomylistXml.fromJson(json.decode(str));
String economylistXmlToJson(EconomylistXml data) => json.encode(data.toJson());
class EconomylistXml {
EconomylistXml({
required this.rss,
});
Rss rss;
factory EconomylistXml.fromJson(Map<String, dynamic> json) => EconomylistXml(
rss: Rss.fromJson(json["rss"]),
);
Map<String, dynamic> toJson() => {
"rss": rss.toJson(),
};
}
class Rss {
Rss({
required this.empty,
required this.channel,
});
Empty empty;
Channel channel;
factory Rss.fromJson(Map<String, dynamic> json) => Rss(
empty: Empty.fromJson(json["\u0024"]),
channel: Channel.fromJson(json["channel"]),
);
Map<String, dynamic> toJson() => {
"\u0024": empty.toJson(),
"channel": channel.toJson(),
};
}
class Channel {
Channel({
required this.title,
required this.link,
required this.description,
required this.language,
required this.copyright,
required this.image,
required this.item,
});
String? title;
String? link;
String? description;
String? language;
String? copyright;
Image image;
List<Item> item;
factory Channel.fromJson(Map<String, dynamic> json) => Channel(
title: json["title"],
link: json["link"],
description: json["description"],
language: json["language"],
copyright: json["copyright"],
image: Image.fromJson(json["image"]),
item: List<Item>.from(json["item"].map((x) => Item.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"title": title,
"link": link,
"description": description,
"language": language,
"copyright": copyright,
"image": image.toJson(),
"item": List<dynamic>.from(item.map((x) => x.toJson())),
};
}
class Image {
Image({
required this.title,
required this.url,
required this.link,
required this.width,
required this.height,
});
String? title;
String? url;
String? link;
String? width;
String? height;
factory Image.fromJson(Map<String, dynamic> json) => Image(
title: json["title"],
url: json["url"],
link: json["link"],
width: json["width"],
height: json["height"],
);
Map<String, dynamic> toJson() => {
"title": title,
"url": url,
"link": link,
"width": width,
"height": height,
};
}
class Item {
Item({
required this.title,
required this.description,
required this.link,
required this.pubDate,
});
String? title;
String? description;
String? link;
String? pubDate;
factory Item.fromJson(Map<String, dynamic> json) => Item(
title: json["title"],
description: json["description"],
link: json["link"],
pubDate: json["pubDate"],
);
Map<String, dynamic> toJson() => {
"title": title,
"description": description,
"link": link,
"pubDate": pubDate,
};
}
class Empty {
Empty({
required this.version,
});
String? version;
factory Empty.fromJson(Map<String, dynamic> json) => Empty(
version: json["version"],
);
Map<String, dynamic> toJson() => {
"version": version,
};
}
This is where i call api :
import 'package:flutter/material.dart';
import 'package:halkaarzhisseler/models/apis/economy_api.dart';
import 'package:http/http.dart' as http;
import '../models/apis/economy_xml.dart';
import 'haberdetail.dart';
class Economy extends StatefulWidget {
const Economy({Key? key}) : super(key: key);
#override
State<Economy> createState() => _EconomyState();
}
class _EconomyState extends State<Economy> {
ScrollController? controller;
final scaffoldKey = GlobalKey<ScaffoldState>();
final url = Uri.parse('https://v1.nocodeapi.com/miktadtahir/xml_to_json/htvLvoPDCwIEyTxa?url=https://ekonomigundemi.com.tr/rss/ekonomi/246.xml');
var counter;
EconomylistXml? haberResult;
Future callHaber() async {
try{
final response = await http.get(url);
if(response.statusCode == 200){
var rss = economylistXmlFromJson(response.body);
if(mounted);
setState(() {
counter = haberResult?.rss.channel.item.length;
haberResult = rss;
});
return rss;
} else {
print(response.statusCode);
}
} catch(e) {
print(e.toString());
}
}
#override
void initState() {
// TODO: implement initState
super.initState();
callHaber();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: false,
automaticallyImplyLeading: false,
title: Text(
'Ekonomi Haberleri'
),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: counter != null ?
ListView.builder(
itemCount: counter,
itemBuilder: (context, index){
return Card(
child: ListTile(
title: Text(haberResult?.rss.channel.item[index].title??""),
onTap: () => Navigator.push(
context, MaterialPageRoute(builder: (context) => HaberDetailScreen( subtitle: haberResult?.rss.channel.item[index].title??"", title: haberResult?.rss.channel.item[index].description??"")),),
),
);
}) : Center(child: CircularProgressIndicator(
)),
),
),
);
}
}
/*class Economy extends StatefulWidget {
const Economy({Key? key}) : super(key: key);
#override
State<Economy> createState() => _EconomyState();
}
class _EconomyState extends State<Economy> {
ScrollController? controller;
final scaffoldKey = GlobalKey<ScaffoldState>();
final url = Uri.parse('https://api.collectapi.com/news/getNews?country=tr&tag=economy&padding=10');
var counter;
Economylist? haberResult;
Future callHaber() async {
try{
Map<String, String> requestHeaders = {
'Content-Type': 'application/json',
'Authorization': 'apikey 3fPhNZfVyrl8dOAkT86niI:3g2OzN57bil8vArOdVE3ka'
};
final response = await http.get(url,headers:requestHeaders);
if(response.statusCode == 200){
var result = economylistFromJson(response.body);
if(mounted);
setState(() {
counter = counter = result.result.length;
haberResult = result;
});
return result;
} else {
print(response.statusCode);
}
} catch(e) {
print(e.toString());
}
}
#override
void initState() {
// TODO: implement initState
super.initState();
callHaber();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: false,
automaticallyImplyLeading: false,
title: Text(
'Ekonomi Haberleri'
),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: counter != null ?
ListView.builder(
itemCount: counter,
itemBuilder: (context, index){
return Card(
child: ListTile(
title: Text(haberResult?.result[index].name??""),
leading: CircleAvatar(
backgroundImage: NetworkImage(haberResult?.result[index].image??""),),
onTap: () => Navigator.push(
context, MaterialPageRoute(builder: (context) => HaberDetailScreen( subtitle: haberResult?.result[index].description??"", title: haberResult?.result[index].name??"",image: haberResult?.result[index].image??"")),),
),
);
}) : Center(child: CircularProgressIndicator(
)),
),
),
);
}
}
*/
I see no error in the console. Only CircularProgressIndicator working. How can i fix this? Thanks for your help
Just switch these two lines:
counter = haberResult?.rss.channel.item.length;
haberResult = rss;
to
haberResult = rss;
counter = haberResult?.rss.channel.item.length;
You are trying to access haberResult before you assign it
Instead of calling api in initState, you should use FutureBuilder like this:
FutureBuilder(
future: callHaber(),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else {
if (snapshot.hasError) {
return Text('has error');
} else {
return ListView.builder(
itemCount: counter,
itemBuilder: (context, index) {
return Card(
child: ListTile(
title: Text(
haberResult?.rss.channel.item[index].title ??
""),
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HaberDetailScreen(
subtitle: haberResult
?.rss.channel.item[index].title ??
"",
title: haberResult?.rss.channel
.item[index].description ??
"")),
),
),
);
});
}
}
},
)
Replace callHaber() function with this
Future callHaber() async {
try{
final response = await http.get(url);
if(response.statusCode == 200){
haberResult = economylistXmlFromJson(response.body);
if(mounted);
setState(() {
counter = haberResult?.rss.channel.item.length;
});
return haberResult;
} else {
print(response.statusCode);
}
} catch(e) {
print(e.toString());
}
}
eg:details about the questions....................................................................I have a model class Name is RasiphalaContent . i want to access main_img,title to display in home page. but not able to access in home page.below i've attached the model class and Home page code please find and check it.
Home Page:
import 'dart:io';
import 'dart:math';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'DetailsPage.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'Model/RasiphalaContent.dart';
var paddingBottom = 48.0;
var androidDeviceInfo;
var identifier;
var token;
var token1;
class HomePage extends StatelessWidget {
final String apiUrl = "https://www.sofikart.com/MobileApi/banners";
final String apiUrl1 =
"https://wayindia.net/indigo/odia_rashifal/rasifhala.php";
Future<RasiphalaContent> fetchData() async {
final response = await http.get(Uri.parse(apiUrl1));
print(response.body);
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return RasiphalaContent.fromJson(jsonDecode(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load album');
}
}
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('ଆଜିର ରାଶିଫଳ'),
centerTitle: true,
),
body: Container(
child: FutureBuilder<RasiphalaContent>(
future: fetchData(),
builder: (BuildContext context, snapshot) {
final data = snapshot.data;
_getId();
if (snapshot.hasData) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 20,
mainAxisSpacing: 25,
),
padding: EdgeInsets.all(13),
shrinkWrap: true,
itemBuilder: (ctx, index) {
return InkWell(
child: Container(
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.all(Radius.circular(12))),
child: Column(
children: [
Expanded(
flex: 9,
child: ClipRRect(
borderRadius:
BorderRadius.all(Radius.circular(12)),
child: Image.network(,
fit: BoxFit.fill)),
),
Expanded(
flex: 2,
child: Text(
title(),
style: TextStyle(
color: Colors.black, fontSize: 17),
)),
],
),
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailsPage(),
),
);
},
);
},
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),
),
);
}
Future<String?> _getId() async {
identifier;
final DeviceInfoPlugin deviceInfoPlugin = new DeviceInfoPlugin();
if (Platform.isAndroid) {
// import 'dart:io'
var build = await deviceInfoPlugin.androidInfo;
identifier = build.androidId!; //UUID for Android
token = await FirebaseMessaging.instance.getToken();
token1 = await FirebaseMessaging.instance.getToken();
login();
}
}
login() async {
final response = await http.post(
"https://wayindia.net/indigo/odia_rashifal/device_create.php",
body: {
//"flag": 1.toString(),
"device_id": identifier,
"device_token": token,
});
final data = jsonDecode(response.body);
int value = data['status'];
String message = data['message'];
if (value == 1) {
print(message);
} else {
print("fail");
print(message);
}
}
}
Model Class :
// To parse this JSON data, do
//
// final rasiphalaContent = rasiphalaContentFromJson(jsonString);
import 'dart:convert';
RasiphalaContent rasiphalaContentFromJson(String str) => RasiphalaContent.fromJson(json.decode(str));
String rasiphalaContentToJson(RasiphalaContent data) => json.encode(data.toJson());
class RasiphalaContent {
RasiphalaContent({
required this.status,
required this.message,
required this.data,
});
int status;
String message;
List<Datum> data;
factory RasiphalaContent.fromJson(Map<String, dynamic> json) => RasiphalaContent(
status: json["status"],
message: json["message"],
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"message": message,
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
Datum({
required this.id,
required this.title,
required this.content,
required this.engTitle,
required this.mainImg,
required this.image2,
required this.image3,
required this.image4,
});
String id;
String title;
String content;
String engTitle;
String mainImg;
String image2;
String image3;
String image4;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
title: json["title"],
content: json["content"],
engTitle: json["eng_title"],
mainImg: json["main_img"],
image2: json["image_2"],
image3: json["image_3"],
image4: json["image_4"],
);
Map<String, dynamic> toJson() => {
"id": id,
"title": title,
"content": content,
"eng_title": engTitle,
"main_img": mainImg,
"image_2": image2,
"image_3": image3,
"image_4": image4,
};
}
I called api request and it worked fine, i used dio client and get data properly. but since last day it dosen't work!. i tried to solve this problem. it shows thousand of line in Logcat. but what is the actual problem? any solution?
This is dio api response
Future<List<ListAlbum>> listData() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
final token = sharedPreferences.getString("token");
String url =
'https://portal-api.jomakhata.com/api/getOrganizationData?token=${token}';
Dio dio = new Dio();
dio.options.headers['Content-Type'] = 'application/json';
final body = {'limit': 10, 'orderBy': 'idEmployee', 'orderType': 'DESC'};
final response = await dio.post(url, data: body);
if (response.statusCode == 200) {
print(response.statusCode);
print(response.data);
return response.data["data"]["data"]
.map<ListAlbum>((json) => ListAlbum.fromJson(json))
.toList();
} else {
throw Exception('Failed!');
}
}
Full Code here
class OrganizationList extends StatefulWidget {
const OrganizationList({Key? key}) : super(key: key);
#override
_OrganizationListState createState() => _OrganizationListState();
}
class _OrganizationListState extends State<OrganizationList> {
late Future<List<ListAlbum>> futureAlbum;
#override
void initState() {
super.initState();
futureAlbum = listData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FutureBuilder<List<ListAlbum>>(
future: futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
print(snapshot.data);
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
final ListAlbum item = snapshot.data![index];
return ListTile(
leading: Text(item.idEmployee!.toString()),
title: Text(item.fullName!),
subtitle: Text(item.officeID!),
trailing: Text(item.designation!),
onTap: () {
Navigator.push(
context, MaterialPageRoute(
builder: (BuildContext context) => DetailsListOrganizationData()),
);
},
);
},
);
} else if (snapshot.hasError) {
return Text('${snapshot.hasError}');
}
return const CircularProgressIndicator();
},
),
),
);
}
}
class ListAlbum {
final int? idEmployee;
final String? avatar;
final String? fullName;
final String? officeID;
final String? email;
final String? designation;
final String? department;
final String? mobileNumber;
final String? workStation;
final String? businessUnit;
ListAlbum({
this.idEmployee,
this.avatar,
this.fullName,
this.officeID,
this.email,
this.designation,
this.department,
this.mobileNumber,
this.workStation,
this.businessUnit,
});
factory ListAlbum.fromJson(Map<String, dynamic> json) {
return ListAlbum(
idEmployee: json['idEmployee'],
avatar: json['avatar'],
fullName: json['fullName'],
officeID: json['officeID'],
email: json['email'],
designation: json['designation'],
department: json['department'],
mobileNumber: json['mobileNumber'],
workStation: json['workStation'],
businessUnit: json['businessUnit'],
);
}
}
so, i think dio client have some problem. but not sure!
I want to add my data in listview.
also tried using this https://flutter.dev/docs/cookbook/lists/long-lists
I got data in futureAlbum, and snapshot has data. but i can't convert these data in listView.builder. so, how to implement listview in FutureBuilder?
body: Center(
child: FutureBuilder<ListAlbum>(
future: futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
print(snapshot.data);
return Text(snapshot.data!.idEmployee.toString()); // in this section i want to add listview
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
return const CircularProgressIndicator();
},
),
),
full code of calling api
class OrganizationList extends StatefulWidget {
const OrganizationList({Key? key}) : super(key: key);
#override
_OrganizationListState createState() => _OrganizationListState();
}
class _OrganizationListState extends State<OrganizationList> {
late Future<ListAlbum> futureAlbum;
#override
void initState() {
super.initState();
futureAlbum = listData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FutureBuilder<ListAlbum>(
future: futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
print(snapshot.data);
return Text(snapshot.data!.idEmployee.toString()); // in this section i want to add listview
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
return const CircularProgressIndicator();
},
),
),
);
}
}
class ListAlbum {
final int idEmployee;
final String avatar;
final String fullName;
final String officeID;
final String email;
final String designation;
final String department;
final String mobileNumber;
final String workStation;
final String businessUnit;
ListAlbum({
required this.idEmployee,
required this.avatar,
required this.fullName,
required this.officeID,
required this.email,
required this.designation,
required this.department,
required this.mobileNumber,
required this.workStation,
required this.businessUnit,
});
factory ListAlbum.fromJson(Map<String, dynamic> json) {
return ListAlbum(
idEmployee: json['idEmployee'],
avatar: json['avatar'],
fullName: json['fullName'],
officeID: json['officeID'],
email: json['email'],
designation: json['designation'],
department: json['department'],
mobileNumber: json['mobileNumber'],
workStation: json['workStation'],
businessUnit: json['businessUnit'],
);
}
}
Future<ListAlbum> listData() async {
final token =
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI4OTksImlzcyI6Imh0dHBzOi8vcG9ydGFsLWFwaS5qb21ha2hhdGEuY29tL2FwaS9hdXRoL2xvZ2luIiwiaWF0IjoxNjI5NTI2OTc1LCJleHAiOjE2Mjk2MTMzNzUsIm5iZiI6MTYyOTUyNjk3NSwianRpIjoiRktiT295eEYwaEpDUXMxdiJ9.o4eM_C4hlluHe9Azk0MspPJtYZ7agdpFA6xwKiijLj8';
String url =
'https://portal-api.jomakhata.com/api/getOrganizationData?token=${token}';
Dio dio = new Dio();
dio.options.headers['Content-Type'] = 'application/json';
final body = {'limit': 5, 'orderBy': 'idEmployee', 'orderType': 'DESC'};
final response = await dio.post(url, data: body);
if (response.statusCode == 200) {
print(response.statusCode);
print(response.data);
var data = ListAlbum.fromJson(response.data["data"]["data"][0]);
return data;
} else {
throw Exception('Failed!');
}
}
What list I want to implement!
First, you have all members is ListAlbum marked as required, but some of your results in the response doesn't have all of these, for example second row has no avatar. You can overcome this by marking these fields as not required, like this (I made here all members optional - adjust it as you need):
class ListAlbum {
final int? idEmployee;
final String? avatar;
final String? fullName;
final String? officeID;
final String? email;
final String? designation;
final String? department;
final String? mobileNumber;
final String? workStation;
final String? businessUnit;
ListAlbum({
this.idEmployee,
this.avatar,
this.fullName,
this.officeID,
this.email,
this.designation,
this.department,
this.mobileNumber,
this.workStation,
this.businessUnit,
});
factory ListAlbum.fromJson(Map<String, dynamic> json) {
return ListAlbum(
idEmployee: json['idEmployee'],
avatar: json['avatar'],
fullName: json['fullName'],
officeID: json['officeID'],
email: json['email'],
designation: json['designation'],
department: json['department'],
mobileNumber: json['mobileNumber'],
workStation: json['workStation'],
businessUnit: json['businessUnit'],
);
}
}
Next, convert your listData function so that it will return a list of ListAlbum objects. You can grab the data from your response, convert and return like this:
Future<List<ListAlbum>> listData() async {
final token =
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI4OTksImlzcyI6Imh0dHBzOi8vcG9ydGFsLWFwaS5qb21ha2hhdGEuY29tL2FwaS9hdXRoL2xvZ2luIiwiaWF0IjoxNjI5NTI2OTc1LCJleHAiOjE2Mjk2MTMzNzUsIm5iZiI6MTYyOTUyNjk3NSwianRpIjoiRktiT295eEYwaEpDUXMxdiJ9.o4eM_C4hlluHe9Azk0MspPJtYZ7agdpFA6xwKiijLj8';
String url =
'https://portal-api.jomakhata.com/api/getOrganizationData?token=${token}';
Dio dio = new Dio();
dio.options.headers['Content-Type'] = 'application/json';
final body = {'limit': 5, 'orderBy': 'idEmployee', 'orderType': 'DESC'};
final response = await dio.post(url, data: body);
if (response.statusCode == 200) {
print(response.statusCode);
print(response.data);
return response.data["data"]["data"]
.map<ListAlbum>((json) => ListAlbum.fromJson(json))
.toList();
} else {
throw Exception('Failed!');
}
}
Finally, change the future return type and create the ListView from this list, this is an example, adjust it:
class _OrganizationListState extends State<OrganizationList> {
late Future<List <ListAlbum>> futureAlbum;
#override
void initState() {
super.initState();
futureAlbum = listData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FutureBuilder<List<ListAlbum>>(
future: futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
print(snapshot.data);
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
final ListAlbum item = snapshot.data![index];
return ListTile(
leading: Text(item.idEmployee.toString()),
title: Text(item.fullName!),
subtitle: Text(item.designation!),
trailing: Text(item.businessUnit!),
);
},
);
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
return const CircularProgressIndicator();
},
),
));
}
}
...and I don't know whether token is a secret or not, but if it is, you should revoke it.
Try this:
Future<List<ListAlbum>> listData() async {
final token =
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI4OTksImlzcyI6Imh0dHBzOi8vcG9ydGFsLWFwaS5qb21ha2hhdGEuY29tL2FwaS9hdXRoL2xvZ2luIiwiaWF0IjoxNjI5NTI2OTc1LCJleHAiOjE2Mjk2MTMzNzUsIm5iZiI6MTYyOTUyNjk3NSwianRpIjoiRktiT295eEYwaEpDUXMxdiJ9.o4eM_C4hlluHe9Azk0MspPJtYZ7agdpFA6xwKiijLj8';
String url =
'https://portal-api.jomakhata.com/api/getOrganizationData?token=${token}';
Dio dio = new Dio();
dio.options.headers['Content-Type'] = 'application/json';
final body = {'limit': 5, 'orderBy': 'idEmployee', 'orderType': 'DESC'};
final response = await dio.post(url, data: body);
if (response.statusCode == 200) {
print(response.statusCode);
print(response.data);
List<ListAlbum> _list=response.data["data"]["data"].map((e)=>ListAlbum.fromJson(e)).toList();
return _list;
} else {
throw Exception('Failed!');
}
}
And your widget to this:
class OrganizationList extends StatefulWidget {
const OrganizationList({Key? key}) : super(key: key);
#override
_OrganizationListState createState() => _OrganizationListState();
}
class _OrganizationListState extends State<OrganizationList> {
late Future<List<ListAlbum>> futureAlbum;
#override
void initState() {
super.initState();
futureAlbum = listData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FutureBuilder<List<ListAlbum>>(
future: futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
print(snapshot.data);
return Column(
children:[
for(ListAlbum item in snapshot.data)
Text(item.idEmployee.toString())]);
//Or you can also use listview.builder here instead of column, but this will work for proof of concept.
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
return const CircularProgressIndicator();
},
),
),
);
}
}
I create an UI with FutureBuilder to show an nested object from my rest api, but i don't know why, but after run my function(in my UI) my console throw me this type of error:
RangeError (index): Invalid value: Only valid value is 0: 1
I try flutter doctor but it not help me,
ps. I can't use itemCount: snapshot.data.length because
Class 'User' has no instance getter 'length'
my code:
#override
void initState(){
super.initState();
userApiService = UserApiService();
_future = getUserData();
}
getUserData() async{
sharedPreferences = await SharedPreferences.getInstance();
int id = sharedPreferences.getInt('id');
return userApiService.getUser(id);
}
#override
Widget build(BuildContext context){
return FutureBuilder(
future: _future,
builder: (context, snapshot){
if(!snapshot.hasData){
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}
// User user = snapshot.data;
return Scaffold(
backgroundColor: Colors.white,
body: Container(
child: ListView.builder(
itemBuilder: (context, i){
User user = snapshot.data;
return GestureDetector(
onTap: () {
//
},
child: Container(
width: 300,
height: 80,
color: Colors.blue,
child: Text(user.myFollows[i].firstName + ' ' + user.myFollows[i].lastName),
),
);
}
)
),
);
},
);
}
model User:
class User {
List<Observations> followedBy;
List<Observations> myFollows;
int id;
String firstName;
String lastName;
User(
{
this.followedBy,
this.myFollows,
this.id,
this.firstName,
this.lastName,
});
factory User.fromJson(Map<String, dynamic> json){
return User(
id: json['id'],
firstName: json['firstName'],
lastName: json['lastName'],
followedBy: parseFollowedBy(json),
myFollows: parseMyFollows(json),
);
}
static List<Observations> parseFollowedBy(json){
var lista = json['followedBy'] as List;
List<Observations> followedByList = lista.map((data) => Observations.fromJson(data)).toList();
return followedByList;
}
static List<Observations> parseMyFollows(myFollowsJson){
var list = myFollowsJson['myFollows'] as List;
List<Observations> myFollowsList = list.map((data) => Observations.fromJson(data)).toList();
return myFollowsList;
}
}
List<User> usersFromJson(String jsonData){
final data = json.decode(jsonData);
return List<User>.from(data.map((item) => User.fromJson(item)));
}
User userFromJson(String jsonData){
final data = json.decode(jsonData);
return User.fromJson(data);
}
String userToJson(User data){
final jsonData = data.toJson();
return json.encode(jsonData);
}
model observations.dart:
class Observations {
final int id;
final String firstName;
final String lastName;
Observations({this.id, this.firstName, this.lastName});
factory Observations.fromJson(Map<String, dynamic> parsedJson) {
return Observations(
id: parsedJson['id'],
firstName: parsedJson['firstName'],
lastName: parsedJson['lastName'],
);
}
}
thanks for any help :)
In this case you have to set itemCount to the lenght of the list you are traversing in the ListView.
I see you are using user.myFollows[i]
So maybe you should use:
itemCount: user.myFollows.length,