Parsing Nested JSON with Flutter (Dart) - flutter

This is the JSON Response I'm getting. I want to Parse the text which says "url" (With. I want to Get this Text)
{
"data": [
{
"id": 1,
"attributes": {
"Title": "My Story",
"Story": "My story is about my life",
"Image": {
"data": {
"id": 1,
"attributes": {
"name": "lifeImage.jpeg",
"alternativeText": "lifeImage.jpeg",
"caption": "lifeImage.jpeg",
"url": "/uploads/lifeImage_0e9293ee8d.jpeg", <-- I want to Get this Text
"previewUrl": null,
"provider": "local"
}
}
}
}
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 3
}
}
}
I easily parsed the Title, Story with the Below Dart File.
But I'm not sure how can I parse the URL text (One with arrow marks says "<-- I want to Get this Text"). Since it's nested one I don't know how to do that. Please help me with this. Thanks
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import 'StoryPage.dart';
void main() => runApp(App());
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My Stories',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const Homepage(),
);
}
}
class Homepage extends StatefulWidget {
const Homepage({Key? key}) : super(key: key);
#override
_HomepageState createState() => _HomepageState();
}
class _HomepageState extends State<Homepage> {
Future<List<Story>> _getStories() async {
var response = await http.get(Uri.parse(
'https://exampleapi.com/api/stories/?populate=Image'));
if (response.statusCode == 200) {
Map responseData = jsonDecode(response.body);
List StoriesList = responseData["data"];
List<Story> stories = [];
for (var storyMap in StoriesList) {
stories.add(Story.fromJson(storyMap["attributes"]));
}
return stories;
} else {
throw Exception('Failed to load stories');
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('My Stories'),
),
body: Container(
child: FutureBuilder(
future: _getStories(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return InkWell(
child: Card(
child: Padding(
padding: const EdgeInsets.only(
top: 32.0, bottom: 32.0, left: 16.0, right: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
snapshot.data[index].title,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => new StoryPage(
snapshot.data[index],
title: snapshot.data[index].title,
body: snapshot.data[index].body,
)));
},
);
},
);
}
},
),
),
);
}
}
class Story {
final String title;
final String body;
Story({required this.title, required this.body});
factory Story.fromJson(Map<String, dynamic> json) {
return Story(
title: json['Title'],
body: json['Story'],
);
}
}

You can simply parse them like this:
final url = json['image']?['data']?['attributes']?['url'];
here we're using question marks (?) in between, because we're not sure that each element is not null, for example, the data under image may be null, so by using question marks, we're staying safe from null exceptions.

I took #Adnan approach and modified it little.
final ImageURL = json['Image']?['data']?['attributes']?['url'] ?? ''
Thanks to GitHub Co-Pilot.

I suggest using this website to generate dart or any other language object from json.
you just need to covert it to null safety.
here a example:
class AnswerResponse {
AnswerResponse({
required this.id,
required this.description,
required this.isAccepted,
required this.isMine,
required this.media,
required this.caseId,
required this.voteUp,
required this.voteDown,
required this.votes,
required this.user,
required this.comment,
required this.createdAt,
});
factory AnswerResponse.fromJson(final String str) => AnswerResponse.fromMap(json.decode(str));
factory AnswerResponse.fromMap(final Map<String, dynamic> json) => AnswerResponse(
id: json["id"],
description: json["description"],
isAccepted: json["isAccepted"],
isMine: json["isMine"],
media: json["media"] == null ? null : List<MediaResponse>.from(json["media"].map((final dynamic x) => MediaResponse.fromMap(x))),
caseId: json["caseId"],
voteUp: json["voteUp"],
voteDown: json["voteDown"],
votes: json["votes"],
user: json["user"] == null ? null : ProfileResponse.fromMap(json["user"]),
comment: json["comment"] == null ? null : List<CommentResponse>.from(json["comment"].map((final dynamic x) => CommentResponse.fromMap(x))),
createdAt: json["createdAt"],
);
final int? id;
final int? caseId;
final int? votes;
final bool? isAccepted;
final bool? isMine;
final bool? voteUp;
final bool? voteDown;
final String? description;
final String? createdAt;
final ProfileResponse? user;
final List<MediaResponse>? media;
final List<CommentResponse>? comment;
}
and to convert json string to dart object:
var data = AnswerResponse.fromMap(jsonString)

Related

How to fetch image from firestore on flutter?

I tried to fetch images and topic and descriptions for each "doc id ", Successfully fetch topic and description but when I tried to fetch image then shows "URL undefined" .For this code I used model class also.And in there I decleard "URL" and in the UI code I called that in an" Imagenetwrok widget".
code
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../articlesModel.dart';
class ViewArticlesScreens extends StatefulWidget {
const ViewArticlesScreens({Key? key}) : super(key: key);
#override
State<ViewArticlesScreens> createState() => _ViewArticlesScreensState();
}
class _ViewArticlesScreensState extends State<ViewArticlesScreens> {
#override
Future<List<Articles>> fetchRecords() async {
var records = await FirebaseFirestore.instance.collection('articles').get();
return mapRecords(records);
}
List<Articles> mapRecords(QuerySnapshot<Map<String, dynamic>> records) {
var _list = records.docs
.map(
(article) => Articles(
id: article.id,
topic: article['topic'],
description: article['description'],
url: article['url'],
),
)
.toList();
return _list;
}
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;
return Scaffold(
body: Column(
children: [
SingleChildScrollView(
child: Column(
//chip words
children: <Widget>[
const SizedBox(height: 10),
SizedBox(
width: width * 0.94,
height: height * 0.30,
child: FutureBuilder<List<Articles>>(
future: fetchRecords(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
List<Articles> data = snapshot.data ?? [];
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return (ListTile(
leading: Image.network(
url,
height: 30,
fit: BoxFit.cover,
),
title: Text(data[index].topic),
subtitle: Text(data[index].description),
tileColor: Colors.red,
));
});
}
}))
],
),
),
],
),
);
}
}
model class
import 'dart:convert';
Articles articlesFromJson(String str) => Articles.fromJson(json.decode(str));
String articlesToJson(Articles data) => json.encode(data.toJson());
class Articles {
Articles({
required this.id,
required this.url,
required this.topic,
required this.description,
});
String id;
String topic;
String description;
String url;
factory Articles.fromJson(Map<String, dynamic> json) => Articles(
id: json["id"] ?? "",
topic: json["topic"] ?? "",
description: json["description"] ?? "",
url: json["url"] ?? "",
);
Map<String, dynamic> toJson() => {
"id": id,
"topic": topic,
"description": description,
"url": url,
};
}
you just set url instead of data[index].url
here try this :
itemBuilder: (context, index) {
return (ListTile(
leading: Image.network(
data[index].url,
height: 30,
fit: BoxFit.cover,
),
title: Text(data[index].topic),
subtitle: Text(data[index].description),
tileColor: Colors.red,
));
});
}

Flutter "A non-null String must be provided to a Text widget."

I am trying to get the data from an API and I get the data, but when I show it on the screen I get this error
Assertion failed: file:///home/builder/hotbuilder/packages/flutter/lib/src/widgets/text.dart:378:10
data != null.
I saw some examples, but I still don't understand how to solve it
This is main.dart
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:flutter_api_git/modelo/repo.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Demo',
home: Home(),
);
}
}
Future<All> fetchRepos() async {
final response =
await http.get(Uri.parse('https://api.github.com/users/IcaroOli/repos'));
if (response.statusCode == 200) {
print(response.body);
return All.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to fetch repos!');
}
}
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
late Future<All> futureRepo;
#override
void initState() {
super.initState();
futureRepo = fetchRepos();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('GitHub API!'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: FutureBuilder<All>(
future: futureRepo,
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Repo> repos = <Repo>[];
for (int i = 0; i < snapshot.data!.repos.length; i++) {
repos.add(
Repo(
name: snapshot.data.repos[i].name,
description: snapshot.data!.repos[i].description,
htmlUrl: snapshot.data!.repos[i].htmlUrl,
stargazersCount: snapshot.data!.repos[i].stargazersCount,
),
);
}
return ListView(
children: repos
.map(
(r) => Card(
color: Colors.blue[300],
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
r.name,
style: const TextStyle(fontSize: 30.0),
),
Text(r.stargazersCount.toString()),
],
),
Text(
r.description,
style: const TextStyle(fontSize: 23.0),
),
Text(r.htmlUrl),
],
),
),
),
)
.toList(),
);
} else if (snapshot.hasError) {
return const Center(
child: Text('Error!'),
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
),
);
}
}
This is repo.dart
class Repo {
String name;
String htmlUrl; // hmtl_url
int stargazersCount; //stargazers_count
String description;
Repo(
{required this.name,
required this.htmlUrl,
required this.stargazersCount,
required this.description});
factory Repo.fromJson(Map<String, dynamic> json) {
return Repo(
name: json['name'],
htmlUrl: json['html_url'],
stargazersCount: json['stargazers_count'],
description: json['description'],
);
}
}
class All {
List<Repo> repos;
All({required this.repos});
factory All.fromJson(List<dynamic> json) {
List<Repo> repos = <Repo>[];
repos = json.map((r) => Repo.fromJson(r)).toList();
return All(repos: repos);
}
}
class Repo {
String name;
String htmlUrl; // hmtl_url
int stargazersCount; //stargazers_count
String description;
Repo(
{required this.name,
required this.htmlUrl,
required this.stargazersCount,
required this.description});
factory Repo.fromJson(Map<String, dynamic> json) {
return Repo(
name: json['name'],
htmlUrl: json['html_url'],
stargazersCount: json['stargazers_count'],
description: json['description'],
);
}
}
class All {
List<Repo> repos;
All({required this.repos});
factory All.fromJson(List<dynamic> json) {
List<Repo> repos = <Repo>[];
repos = json.map((r) => Repo.fromJson(r)).toList();
return All(repos: repos);
}
}
This happens when you pass a null value to a text widget.
Try adding empty string if the value is null.
Text(r.name ?? ""),
One way to make sure they are never null is to provide fallback values in the factory of Repo, for example an empty string, like this:
factory Repo.fromJson(Map<String, dynamic> json) {
return Repo(
name: json['name'] ?? "",
htmlUrl: json['html_url'] ?? "",
stargazersCount: json['stargazers_count'] ?? 0,
description: json['description'] ?? "",
);
}

Fetch data from API, but the list is empty, it used to work 30 mins ago

Fetching from the api should be right, but it's not working since my list of "_movies" is empty. It was good looking application 2 hours ago and i dont know what i changed to do this.
It returns either nothing when itemCount:_movies.length or error "invalid value: valid value range is empty: 0. I'm stuck on this.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:task/models/movies.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> {
List<Movie> _movies = <Movie>[];
var moviesUrl =
'https://raw.githubusercontent.com/FEND16/movie-json-data/master/json/movies-coming-soon.json';
Future<List<Movie>> getMovies() async {
http.Response res = await http.get(Uri.parse(moviesUrl));
try {
if (res.statusCode == 200) {
List<dynamic> movies = json.decode(res.body);
return movies.map((e) => Movie.fromJson(e)).toList();
} else {
return <Movie>[];
}
} catch (e) {
// print(e);
return <Movie>[];
}
}
#override
void initState() {
getMovies().then((value) {
setState(() {
_movies.addAll(value);
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Movies"),
),
body: ListView.builder(
itemCount: _movies.length,
itemBuilder: (context, index) {
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
_movies[index].title,
style:
TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
),
Text(
_movies[index].genres.toString(),
style: TextStyle(
fontSize: 16,
),
),
],
),
),
);
}),
);
}
}
seems like _movies.lenght is 0, but somehow it worked right 2 hours ago and i didnt change a thing
class Movie {
String id;
String title;
String year;
List genres;
// List ratings;
String poster; //image
// String contentRating;
String duration;
// DateTime releaseDate;
// int averageRating;
String originalTitle;
String storyline;
List actors;
// String imdbRating;
String posterurl; //image
Movie({
required this.id,
required this.title,
required this.year,
required this.genres,
// required this.ratings,
required this.poster,
// required this.contentRating,
required this.duration,
// required this.releaseDate,
// required this.averageRating,
required this.originalTitle,
required this.storyline,
required this.actors,
// required this.imdbRating,
required this.posterurl,
});
factory Movie.fromJson(Map<String, dynamic> json) {
return Movie(
id: json["id"],
title: json["title"],
year: json["year"],
genres: json["genres"],
// ratings: json["ratnigs"],
poster: json["poster"],
// contentRating: json["contentRating"],
duration: json["duration"],
// releaseDate: json["releaseDate"],
// averageRating: json["averageRating"],
originalTitle: json["originalTitle"],
storyline: json["storyline"],
actors: json["actors"],
// imdbRating: json["imdbRating"],
posterurl: json["posterurl"]);
}
}
I believe the error must be on this line:
getMovies().then((value) {
setState(() {
_movies.addAll(value);
});
});
I think dart is confused about rebuilding the _movies variable because you are modifying it instead of reassigning it. If I am right, the solution is as simple as reassigning _movies:
getMovies().then((value) {
setState(() {
_movies = [..._movies, ...value]
});
});

Flutter. When I fetch data from API showing StatusCode 403(Failed to load post)?

eg: details about the questions ..........................................................................
When I want to fetch multiple objects from an array showing status code 403(Failed to load post).and API having a header key I have implemented it also. but showing failed to load post status code 403.
{
"status": 1,
"msg": "7 banners found",
"data": [
{
"id": "14",
"image": "https://www.sofikart.com/admin/upload/app_banner/1635945056.jpeg",
"cat_id": "4",
"product_id": "81",
"url": null,
"status": "Active",
"ordering": "0",
"updated": "2021-11-03 06:10:56"
},
{
"id": "7",
"image": "https://www.sofikart.com/admin/upload/app_banner/1642082634.jpeg",
"cat_id": "4",
"product_id": "111",
"url": null,
"status": "Active",
"ordering": "1",
"updated": "2021-10-28 04:53:26"
}
]
}
controller
-----------
import 'dart:io';
import 'package:fm_sidharth/model/post.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
final String url = 'https://www.sofikart.com/MobileApi/banners';
Future<List<Post>> fetchPost() async {
final response = await http.get(
url, headers: {HttpHeaders.authorizationHeader: 'SOFIKART-*2021#',},);
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON.
final result = json.decode(response.body);
List<Post> posts =
result.map<Post>((model) => new Post.fromJson(model)).toList();
return posts;
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
Future<String> saveNetworkImageToPhoto(String url, String title,
{bool useCache: true}) async {
var data = await getNetworkImageData(url, useCache: useCache);
var filePath = await ImagePickerSaver.saveFile(fileData: data, title: title);
return filePath;
}
class ImagePickerSaver {
static saveFile({fileData, String title}) {}
}
getNetworkImageData(String url, {booluseCache, bool
useCache}) {
}
model
// To parse this JSON data, do
//
// final welcome = welcomeFromJson(jsonString);
import 'dart:convert';
Post welcomeFromJson(String str) => Post.fromJson(json.decode(str));
String welcomeToJson(Post data) => json.encode(data.toJson());
class Post {
Post({
this.status,
this.msg,
this.data,
});
int status;
String msg;
List<Datum> data;
factory Post.fromJson(Map<String, dynamic> json) => Post(
status: json["status"],
msg: json["msg"],
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
String get catId => null;
get image => null;
Map<String, dynamic> toJson() => {
"status": status,
"msg": msg,
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
Datum({
this.id,
this.image,
this.catId,
this.productId,
this.url,
this.status,
this.ordering,
this.updated,
});
String id;
String image;
String catId;
String productId;
dynamic url;
String status;
String ordering;
DateTime updated;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
image: json["image"],
catId: json["cat_id"],
productId: json["product_id"],
url: json["url"],
status: json["status"],
ordering: json["ordering"],
updated: DateTime.parse(json["updated"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"image": image,
"cat_id": catId,
"product_id": productId,
"url": url,
"status": status,
"ordering": ordering,
"updated": updated.toIso8601String(),
};
}
home
import 'package:flutter/material.dart';
import 'package:fm_sidharth/Controller/postController.dart';
import 'package:fm_sidharth/model/post.dart';
import 'package:fm_sidharth/page/postdetails.dart';
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Future<List<Post>> posts;
_HomePageState() {
posts = fetchPost();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Fetch Data Example'),
),
body: FutureBuilder<List<Post>>(
future: posts,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return FlatButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
PostDetails(snapshot.data[index])),
);
},
child: Card(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
snapshot.data[index].catId,
style: TextStyle(
color: Colors.black,
fontSize: 22,
fontWeight: FontWeight.bold,
),
),
),
SizedBox(
height: 10,
),
FadeInImage.assetNetwork(
image: snapshot.data[index].image,
placeholder: 'assets/images/noimage.png',
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
IconButton(
icon: Icon(Icons.favorite_border),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.share),
onPressed: () {
},
),
IconButton(
icon: Icon(Icons.save),
onPressed: () {
saveNetworkImageToPhoto(
snapshot.data[index].image,snapshot.data[index].catId).then((value){
});
},
),
],
)
],
),
),
);
});
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return Center(child: CircularProgressIndicator());
},
),
);
}
}
I have this error too some times, I think this about restrict that google set on you country. please use a proxy. I hope my answer helping to you :)

what simple way to collect data and arrange in horizontal scrolling view in flutter [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
this is the service code below:
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
class CarServices {
Future<List> getCars() async {
String url = "https://rider.spatrum.com/api/select_rides";
http.Response response = await http.get(url);
Map values = jsonDecode(response.body);
return values["data"];
//print(values["data"]);
}
}
the above returns json value
You can copy paste run full code below
You can use ListView.builder with Axis.horizontal
return Container(
height: 100,
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Container(
width: 100,
child: Card(
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.data,
this.message,
});
List<Car> data;
String message;
factory Payload.fromJson(Map<String, dynamic> json) => Payload(
data: List<Car>.from(json["data"].map((x) => Car.fromJson(x))),
message: json["message"],
);
Map<String, dynamic> toJson() => {
"data": List<dynamic>.from(data.map((x) => x.toJson())),
"message": message,
};
}
class Car {
Car({
this.id,
this.vehicletype,
this.displayname,
this.icon,
this.baseFare,
this.baseKm,
this.isenable,
this.seats,
this.createdAt,
this.updatedAt,
this.deletedAt,
});
int id;
String vehicletype;
String displayname;
dynamic icon;
String baseFare;
String baseKm;
String isenable;
String seats;
DateTime createdAt;
DateTime updatedAt;
dynamic deletedAt;
factory Car.fromJson(Map<String, dynamic> json) => Car(
id: json["id"],
vehicletype: json["vehicletype"],
displayname: json["displayname"],
icon: json["icon"],
baseFare: json["base_fare"],
baseKm: json["base_km"],
isenable: json["isenable"],
seats: json["seats"],
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
deletedAt: json["deleted_at"],
);
Map<String, dynamic> toJson() => {
"id": id,
"vehicletype": vehicletype,
"displayname": displayname,
"icon": icon,
"base_fare": baseFare,
"base_km": baseKm,
"isenable": isenable,
"seats": seats,
"created_at": createdAt.toIso8601String(),
"updated_at": updatedAt.toIso8601String(),
"deleted_at": deletedAt,
};
}
class CarServices {
Future<List<Car>> getCars() async {
String url = "https://rider.spatrum.com/api/select_rides";
http.Response response = await http.get(url);
Map values = jsonDecode(response.body);
//return values["data"];
return List<Car>.from(values["data"].map((x) => Car.fromJson(x)));
//print(values["data"]);
}
}
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> {
Future<List<Car>> _future;
CarServices _carServices = CarServices();
#override
void initState() {
_future = _carServices.getCars();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FutureBuilder(
future: _future,
builder: (context, AsyncSnapshot<List<Car>> 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 Container(
height: 100,
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Container(
width: 100,
child: Card(
elevation: 6.0,
child: Padding(
padding: const EdgeInsets.only(
top: 6.0,
bottom: 6.0,
left: 8.0,
right: 8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Text(snapshot.data[index].vehicletype
.toString()),
Text(
"seats ${snapshot.data[index].seats}",
),
],
),
)),
);
}),
);
}
}
}));
}
}
Use a listview.Builder inside a Future Builder. Since you are performing an async operation, future builder is needed to get data correctly.
https://medium.com/nonstopio/flutter-future-builder-with-list-view-builder-d7212314e8c9