Flutter Failed assertion: boolean expression must not be null - json

I am on Vipin Vijayan's tutorial on parsing JSON in ListView following Flutter's fetch data from the internet cookbook and getting the following error:
═══════════════════════════════════ Exception caught by widgets library
═══════════════════════════════════ The following assertion was thrown
building MyApp(dirty, state: _MyAppState#a2d98): Failed assertion:
boolean expression must not be null
The relevant error-causing widget was MyApp
package:le_moineau/main.dart:35 When the exception was thrown, this
was the stack
#0 _MyAppState.build package:le_moineau/main.dart:70
#1 StatefulElement.build package:flutter/…/widgets/framework.dart:4802
#2 ComponentElement.performRebuild package:flutter/…/widgets/framework.dart:4685
#3 StatefulElement.performRebuild package:flutter/…/widgets/framework.dart:4857
#4 Element.rebuild package:flutter/…/widgets/framework.dart:4379 ...
Here is the code to my Users.dart parsed using https://app.quicktype.io/
// To parse this JSON data, do
//
// final users = usersFromJson(jsonString);
import 'dart:convert';
List<User> usersFromJson(String str) =>
List<User>.from(json.decode(str).map((x) => User.fromJson(x)));
String usersToJson(List<User> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class User {
User({
this.userId,
this.id,
this.title,
this.completed,
});
int userId;
int id;
String title;
bool completed;
factory User.fromJson(Map<String, dynamic> json) => User(
userId: json["userId"],
id: json["id"],
title: json["title"],
completed: json["completed"],
);
Map<String, dynamic> toJson() => {
"userId": userId,
"id": id,
"title": title,
"completed": completed,
};
}
and here's my main.dart code:
import 'dart:async';
//import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'others/Users.dart';
class MyHttpOverrides extends HttpOverrides {
#override
HttpClient createHttpClient(SecurityContext context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}
Future<List<User>> getUsers() async {
final response =
await http.get(Uri.https('jsonplaceholder.typicode.com', 'todos'));
//await http.get("https://192.168.1.4:8081/json/todos.json");
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
final List<User> users = usersFromJson(response.body);
return users;
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load users');
}
}
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<User> _users;
bool _loading;
#override
void initState() {
HttpOverrides.global = new MyHttpOverrides();
super.initState();
_loading = true;
getUsers().then((users) {
setState(() {
_users = users;
_loading = false;
});
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text(_loading ? 'Loading...' : 'Users'),
),
body: Container(
color: Colors.white,
child: ListView.builder(
itemCount: null == _users ? 0 : _users.length,
itemBuilder: (context, index) {
User user = _users[index];
return ListTile(
title: Text('This is a test'),
subtitle: Text(user.title),
);
}),
),
),
);
}
}
I get the same error even when I use Vipin's stock Widget Build code. Could someone take a look and give me some advice please?

try to initialize true value in bool variable
bool _loading = true;
and remove _loading = true; in initState()

Because Null Safety coming with Flutter 2.0.x, bool _loading; is not permitted, so you do either bool? _loading; or bool _loading = true;. ? means your variable accepts null-values.
UPDATE: Inserting code
NetService
class NetService {
...
static Future<T?> getJson<T>(String url, {int okCode = 200}) {
return http.get(Uri.parse(url))
.then((response) {
if (response.statusCode == okCode) {
return jsonDecode(response.body) as T;
}
_printDataNotOK(response);
return null;
})
.catchError((err) => _printError(err));
}
....
}
json_placeholder_service.dart
import 'dart:async';
import 'package:jsonplaceholder/services/networking.dart';
class JsonPlaceholderService {
static const _baseUrl = 'https://jsonplaceholder.typicode.com';
/* ---------------------------------------------------------------------------- */
static Future<List?> _doGet(String path) async {
return await NetService.getJson<List>(_baseUrl + path)
.whenComplete(() => print('\nFetching done!'));
}
/* ---------------------------------------------------------------------------- */
static Future<List?> fetchTodos() => _doGet('/todos');
}
home_page.dart
import 'package:flutter/material.dart';
import 'package:jsonplaceholder/services/json_placeholder_service.dart';
class HomePage extends StatelessWidget {
/* ---------------------------------------------------------------------------- */
const HomePage({Key? key}) : super(key: key);
/* ---------------------------------------------------------------------------- */
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Hi!'),
centerTitle: true,
),
body: SingleChildScrollView(
child: FutureBuilder<List?>(
future: JsonPlaceholderService.fetchTodos(),
builder: (context, snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState == ConnectionState.done) {
var data = snapshot.data;
if (data != null && data.isNotEmpty) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: List<Widget>.generate(data.length, (i) {
var item = data[i];
return Text('${item['userId']} - ${item['id']} - ${item['title']}');
}),
);
}
return Text('No data received!');
}
return CircularProgressIndicator();
},
),
),
);
}
}
Result:

Related

Flutter - Pass variable to another screen for URL GET JSON

I'm new to Flutter. On my HOME screen I have a ListView with fetched Json. I want to pass JSON variable ex:id on Tap to the next screen/class 'contantPage' to show another Json loaded from URL with id added.
ex.https:/example.com/myjson.php?id=1
Please! Show me the way.
main.dart
onTap: () {
Navigator.push(context,MaterialPageRoute(
builder(context)=>ContentPage(
photo: photos[index]
)),);},
And in my ContentPage.dart should add id value to URL as GET ex:?id=1
Future<Album> fetchAlbum() async {
// final query1 = Text(photo.publishDate);
final response = await http
.get(Uri.parse('https://jsonplaceholder.typicode.com/albums.php?id=I WANT ID HERE'));
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return Album.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');
}
}
class Album {
final int userId;
final int id;
final String title;
Album({
required this.userId,
required this.id,
required this.title,
});
factory Album.fromJson(Map<String, dynamic> json) {
return Album(
userId: json['userId'],
id: json['id'],
title: json['title'],
);
}
}
//void main() => runApp(MyApp());
class ContentPage extends StatefulWidget {
// ContentPage({Key? key, Photo photo}) : super(key: key);
ContentPage({Key? key, required Photo photo}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<ContentPage> {
late Future<Album> futureAlbum;
#override
void initState() {
super.initState();
futureAlbum = fetchAlbum();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Fetch Data Example'),
),
body: Center(
child: FutureBuilder<Album>(
future: futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data!.title);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
),
),
);
}
}
Like the photo pass your photosid as follows:
onTap: () {
Navigator.push(context,MaterialPageRoute(
builder(context)=>ContentPage(
photo: photos[index],
id:photos[index].id,
)),);},
And then in ContentPage create constructor as follows:
class ContentPage extends StatefulWidget {
Photo photo;
String id;
ContentPage({Key? key, required this.photo,required this.id,}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
In initstate pass your id as follows:
#override
void initState() {
super.initState();
futureAlbum = fetchAlbum(widget.id);
}
And finally your fetchAlbum as follows:
Future<Album> fetchAlbum(var id) async {
// final query1 = Text(photo.publishDate);
final response = await http
.get(Uri.parse('https://jsonplaceholder.typicode.com/albums.php?id=id'));
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return Album.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');
}
}
I can't understand how to display more than 1 field with my code. I have title field and contentIntro field from Json and want to show all together.
body: Center(
child: FutureBuilder<Album>(
future: futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Center(
child: Text(snapshot.data!.contentIntro),
//child: Text(snapshot.data!.Title),
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
),

Im getting a - type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>' error

I have a list of map in json and Im trying to render 'title' on a list.
Im reading data through through an api (http.get) then parse it.
I want to show the title in a list.
Here's my code...
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Getting the data
Future<Welcome> fetchAlbum() async {
final response = await http.get('https://jsonplaceholder.typicode.com/posts');
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return Welcome.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');
}
}
Convert to json
List<Welcome> welcomeFromJson(String str) =>
List<Welcome>.from(json.decode(str).map((x) => Welcome.fromJson(x)));
String welcomeToJson(List<Welcome> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
Model class Welcome
class Welcome {
Welcome({
this.userId,
this.id,
this.title,
this.body,
});
int userId;
int id;
String title;
String body;
factory Welcome.fromJson(Map<String, dynamic> json) => Welcome(
userId: json["userId"],
id: json["id"],
title: json["title"],
body: json["body"],
);
Map<String, dynamic> toJson() => {
"userId": userId,
"id": id,
"title": title,
"body": body,
};
}
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Future<Welcome> futureAlbum;
#override
void initState() {
super.initState();
futureAlbum = fetchAlbum();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Fetch Data Example'),
),
body: Center(
child: FutureBuilder<Welcome>(
future: futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
return new Text(snapshot.data.title);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
),
),
);
}
}
Im getting an error saying " type 'List' is not a subtype of type 'Map<String, dynamic>' "
Change your fetchAlbum function to this
Future<List<Welcome>> fetchAlbum() async {
final response =
await http.get('https://jsonplaceholder.typicode.com/posts');
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
// return Welcome.fromJson(jsonDecode(response.body));
var jsonData = jsonDecode(response.body);
List<Welcome> welcome = [];
for (var v in jsonData) {
Welcome w1 = Welcome(
userId: v['userId'],
id: v['id'],
title: v['title'],
body: v['body']);
welcome.add(w1);
}
return welcome;
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load album');
}
}
The FutureBuider widget will be this
child: FutureBuilder(
future: fetchAlbum(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Container(
margin: EdgeInsets.all(8),
child: Column(
children: [
Text("User Id = ${snapshot.data[index].userId}"),
Text("Id = ${snapshot.data[index].id}"),
Text("Title = ${snapshot.data[index].title}"),
Text("Body = ${snapshot.data[index].body}"),
],
),
);
});
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),

Flutter FutureBuilder with REST JSON paging

I take JSON data to Future<List<Data>> _DataList; with this method
and URL like https://nomer.biz.ua/mobile/kievstar?page=1
Future<List<Data>> getData(int pageCount) async {
String url = Uri.encodeFull("https://nomer.biz.ua/mobile/kievstar?page=$pageCount");
var response = await http.get(url, headers: {"Accept": "application/json"}).timeout(const Duration(seconds: 10));
final Map res = json.decode(response.body);
Response model = Response.fromJson(res);
page++;
return model.data;
}
And pass them to FutureBuilder
#override
Widget build(BuildContext context) {
return Scaffold(
body:FutureBuilder(
future: _DataList,
builder: (BuildContext ctx, AsyncSnapshot<dynamic> snapshot){
if (snapshot.connectionState != ConnectionState.done) {
return Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(child: Text("Error"));
}
if (!snapshot.hasData) {
return Center(child: Text("Error"));
}
var dataToShow = snapshot.data;
return ListView.builder(
controller: _controller,
itemCount: dataToShow == null ? 0 : dataToShow.length,
itemBuilder: (context, index) {
final item = dataToShow[index];
return Card(
//SHOW DATA
);
});
}
)
);
}
Invoke new page on
#override
void initState() {
_DataList = getData(page);
super.initState();
_controller.addListener(() {
if (_controller.position.pixels == _controller.position.maxScrollExtent) {
_DataList= getData(page);
}
});
}
The first page is displayed, but others are not processed. I load a new page, at the moment of scrolling the list to its last element. _DataList = getData(page); receives JSON data from 2 pages, but does not pass them to FutureBuilder.
I could not find a real example where url page navigation is implemented and FutureBuilder together.
You can copy paste run full code below
For demo purpose, I insert new page's data before old data to better see effect
Step 1: You can parse data to model Payload, you can see full code for detail
Step 2: Insert new data and return _DataList
Step 3: Define _future to avoid unnecessary rebuild
code snippet
Future<List<Datum>> getData(int pageCount) async {
String url =
Uri.encodeFull("https://nomer.biz.ua/mobile/kievstar?page=$pageCount");
var response = await http.get(url, headers: {
"Accept": "application/json"
}).timeout(const Duration(seconds: 10));
Payload payload = payloadFromJson(response.body);
_DataList.insertAll(0, payload.data);
page++;
return _DataList;
}
#override
void initState() {
_future = getData(page);
super.initState();
_controller.addListener(() {
if (_controller.position.pixels == _controller.position.maxScrollExtent) {
setState(() {
_future = getData(page);
});
}
});
}
FutureBuilder(
future: _future,
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.currentPage,
this.data,
this.firstPageUrl,
this.from,
this.lastPage,
this.lastPageUrl,
this.nextPageUrl,
this.path,
this.perPage,
this.prevPageUrl,
this.to,
this.total,
});
int currentPage;
List<Datum> data;
String firstPageUrl;
int from;
int lastPage;
String lastPageUrl;
String nextPageUrl;
String path;
int perPage;
dynamic prevPageUrl;
int to;
int total;
factory Payload.fromJson(Map<String, dynamic> json) => Payload(
currentPage: json["current_page"],
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
firstPageUrl: json["first_page_url"],
from: json["from"],
lastPage: json["last_page"],
lastPageUrl: json["last_page_url"],
nextPageUrl: json["next_page_url"],
path: json["path"],
perPage: json["per_page"],
prevPageUrl: json["prev_page_url"],
to: json["to"],
total: json["total"],
);
Map<String, dynamic> toJson() => {
"current_page": currentPage,
"data": List<dynamic>.from(data.map((x) => x.toJson())),
"first_page_url": firstPageUrl,
"from": from,
"last_page": lastPage,
"last_page_url": lastPageUrl,
"next_page_url": nextPageUrl,
"path": path,
"per_page": perPage,
"prev_page_url": prevPageUrl,
"to": to,
"total": total,
};
}
class Datum {
Datum({
this.id,
this.nomerT,
this.datumOperator,
this.ourPrice,
});
int id;
String nomerT;
Operator datumOperator;
int ourPrice;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
nomerT: json["nomer_t"],
datumOperator: operatorValues.map[json["operator"]],
ourPrice: json["our_price"],
);
Map<String, dynamic> toJson() => {
"id": id,
"nomer_t": nomerT,
"operator": operatorValues.reverse[datumOperator],
"our_price": ourPrice,
};
}
enum Operator { KV }
final operatorValues = EnumValues({"kv": Operator.KV});
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 page = 1;
List<Datum> _DataList = [];
Future<List<Datum>> _future;
ScrollController _controller = ScrollController();
Future<List<Datum>> getData(int pageCount) async {
String url =
Uri.encodeFull("https://nomer.biz.ua/mobile/kievstar?page=$pageCount");
var response = await http.get(url, headers: {
"Accept": "application/json"
}).timeout(const Duration(seconds: 10));
Payload payload = payloadFromJson(response.body);
_DataList.insertAll(0, payload.data);
page++;
return _DataList;
}
#override
void initState() {
_future = getData(page);
super.initState();
_controller.addListener(() {
if (_controller.position.pixels == _controller.position.maxScrollExtent) {
setState(() {
_future = getData(page);
});
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: _future,
builder: (BuildContext ctx, AsyncSnapshot<List<Datum>> snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(child: Text("Error"));
}
if (!snapshot.hasData) {
return Center(child: Text("Error"));
}
var dataToShow = snapshot.data;
return ListView.builder(
controller: _controller,
itemCount: dataToShow == null ? 0 : dataToShow.length,
itemBuilder: (context, index) {
final item = dataToShow[index];
return Card(
child: ListTile(
title: Text(dataToShow[index].id.toString()),
subtitle: Text(dataToShow[index].ourPrice.toString()),
),
);
});
}));
}
}

Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic>' in type cast?

here is the response
{
"overview": "A ticking-time-bomb insomniac and a slippery soap salesman channel primal male aggression into a shocking new form of therapy. Their concept catches on, with underground "fight clubs" forming in every town, until an eccentric gets in the way and ignites an out-of-control spiral toward oblivion.",
"title": "Fight Club",
}
the model
class Movies {
String title;
String overview;
Movies(
{this.title , this.overview});
factory Movies.fromJson(Map <String, dynamic> parsedJson){
return Movies(title: parsedJson['title'] , overview: parsedJson['overview']);
}
}
and
Future <List<Movies>> fetchMovies () async {
var response = await http.get(url);
var jsonData = jsonDecode(response.body) as List ;
List<Movies> movies = jsonData.map((e) => Movies.fromJson(e)).toList();
print(movies.length);
return movies;
}
I get this error (Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List' in type cast) no matter what i do
You tried to cast jsonData as List but the decoder says it's of type Map (Also your response shows its of type Map)
Future <List<Movies>> fetchMovies () async {
var response = await http.get(url);
var jsonData = jsonDecode(response.body);
if(jsonData is List) //check if it's a List
return List<Movies>.from(jsonData.map(map) => Movies.fromJson(map));
else if(jsonData is Map) //check if it's a Map
return [Movies.fromJson(jsonData)]; //return a List of length 1
}
You can copy paste run full code below
You can use moviesFromJson and display with FutureBuilder
code snippet
List<Movies> moviesFromJson(String str) =>
List<Movies>.from(json.decode(str).map((x) => Movies.fromJson(x)));
if (response.statusCode == 200) {
return moviesFromJson(jsonString);
working demo
full code
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
List<Movies> moviesFromJson(String str) =>
List<Movies>.from(json.decode(str).map((x) => Movies.fromJson(x)));
String moviesToJson(List<Movies> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Movies {
Movies({
this.overview,
this.title,
});
String overview;
String title;
factory Movies.fromJson(Map<String, dynamic> json) => Movies(
overview: json["overview"],
title: json["title"],
);
Map<String, dynamic> toJson() => {
"overview": overview,
"title": title,
};
}
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<List<Movies>> _future;
Future<List<Movies>> fetchMovies() async {
String jsonString = '''
[{
"overview" : "with underground \\"fight clubs\\" forming in every town, until an eccentric gets in the way and ignites an out-of-control spiral toward oblivion",
"title" : "Fight Club"
},
{
"overview" : "test overview",
"title" : "test title"
}
]
''';
var response = http.Response(jsonString, 200);
if (response.statusCode == 200) {
return moviesFromJson(jsonString);
} else {
print(response.statusCode);
}
}
#override
void initState() {
_future = fetchMovies();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FutureBuilder(
future: _future,
builder: (context, AsyncSnapshot<List<Movies>> 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.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[index].title),
Spacer(),
Expanded(
child: Text(
snapshot.data[index].overview,
),
),
],
),
));
});
}
}
}));
}
}
Just check out he answer
[
{
"overview":"A ticking-time-bomb insomniac and a slippery soap salesman channel primal male aggression into a shocking new form of therapy. Their concept catches on, with underground \"fight clubs\" forming in every town, until an eccentric gets in the way and ignites an out-of-control spiral toward oblivion.",
"title":"Fight Club"
},
{
"overview":"A ticking-time-bomb insomniac and a slippery soap salesman channel primal male aggression into a shocking new form of therapy. Their concept catches on, with underground fight clubs forming in every town, until an eccentric gets in the way and ignites an out-of-control spiral toward oblivion.",
"title":"second Club"
}
]
Model
// To parse this JSON data, do
//
// final movies = moviesFromJson(jsonString);
import 'dart:convert';
List<Movies> moviesFromJson(String str) => List<Movies>.from(json.decode(str).map((x) => Movies.fromJson(x)));
String moviesToJson(List<Movies> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Movies {
Movies({
this.overview,
this.title,
});
String overview;
String title;
factory Movies.fromJson(Map<String, dynamic> json) => Movies(
overview: json["overview"],
title: json["title"],
);
Map<String, dynamic> toJson() => {
"overview": overview,
"title": title,
};
}
ui page :
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:json_parsing_example/models.dart';
// To parse this JSON data, do
//
// final user = userFromJson(jsonString);
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Users'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _isLoading = false;
List<Movies> dataList = List();
Future<String> loadFromAssets() async {
return await rootBundle.loadString('json/parse.json');
}
#override
void initState() {
super.initState();
getData();
}
getData() async {
setState(() {
_isLoading = true;
});
String jsonString = await loadFromAssets();
final movies = moviesFromJson(jsonString);
dataList = movies;
setState(() {
_isLoading = false;
});
}
// In your case you just check out this code check out the model class
/* Future <List<Movies>> fetchMovies () async {
var response = await http.get(url);
return moviesFromJson(response.body);
} */
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: _isLoading
? Center(
child: CircularProgressIndicator(),
)
: Container(
child: ListView.builder(
itemCount: dataList.length,
shrinkWrap: true,
itemBuilder: (context, i) {
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(dataList[i].overview),
));
}),
),
);
}
}
And on thing to tell is the value for the overview has the double quotes which is why there might be some parsing problem just check the code and let me know if it works.

JSON Array to JSON Object

I'm using a HTTP request that gets a JSON array and pushes this into a JSON object which is read by a list view. I'm having difficulty forcing the JSON array into a JSON object so I'm currently calling each object once via json.decode(response.body)[0]. How can I cast the JSON Array to a JSON Object and have the list view read this entire JSON object?
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<Post> fetchPost() async {
final url = <my_url>;
final response =
await http.get(url);
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON.
print(json.decode(response.body));
// TODO: Identify a way to convert JSON Array to JSON Object
return Post.fromJson(json.decode(response.body)[0]);
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
class Post {
final String title;
Post({this.title});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
title: json['title']
);
}
}
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Future<Post> post;
#override
void initState() {
super.initState();
post = fetchPost();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Fetch Data Example'),
),
body: Center(
child: FutureBuilder<Post>(
future: post,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.title);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
),
),
);
}
}
try this,
Future<List<Post>> fetchPost() async {
final url = <my_url>;
final response =
await http.get(url);
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON.
print(json.decode(response.body));
List<dynamic> responseList = json.decode(response.body);
// TODO: Identify a way to convert JSON Array to JSON Object
List<Post> tempList = [];
responseList.forEach((f) {
tempList.add(Post.fromJson(f));
});
return tempList;
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
class Post {
final int id;
final String title;
Post({this.id, this.title});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(id: json['id'], title: json['title']);
}
}
class _Frag_CommitteeState extends State<Frag_Committee> {
Future<List<Post>> post;
#override
void initState() {
super.initState();
post = fetchPost();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Fetch Data Example'),
),
body: Center(
child: FutureBuilder<List<Post>>(
future: post,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return Text(snapshot.data[index].title);
});
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
),
);
}
}