Flutter - Pass variable to another screen for URL GET JSON - 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();
},
),
),

Related

Flutter Failed assertion: boolean expression must not be null

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:

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()),
),
);
});
}));
}
}

Store List of Objects or Map in SharedPreference using dart

I am returning data from MySQL in JSON using this piece of code
while($row = mysqli_fetch_assoc($queryResult)) {
$resultArray[]=$row;
}
echo json_encode($resultArray);
The result is in this format
[{
"reg_number": "FA16-BCS-106",
"teacher_id": "1",
"qr_code": "jamshaid",
"course_name": "COURSE 1"
}, {
"reg_number": "FA16-BCS-106",
"teacher_id": "EMP_FA10_10",
"qr_code": "jamoo",
"course_name": "COURSE 2"
}]
I am decoding the response and storing it in a list using this method which is working fine.
class Student {
final String reg_number;
final String teacher_id;
final String qr_code;
final String course_name;
Student({this.reg_number, this.teacher_id, this.qr_code, this.course_name});
factory Student.fromJson(Map<String, dynamic> json) {
return Student(
reg_number: json['reg_number'],
teacher_id: json['teacher_id'],
qr_code: json['qr_code'],
course_name: json['course_name'],
);
}
}
final parsed =
json.decode(jsonResponse.body).cast<Map<String, dynamic>>();
List<Student> st =
parsed.map<Student>((json) => Student.fromJson(json)).toList();
I am trying to store this List of objects of Student class in SharedPreference using version ^0.5.6. There is no direct method available for this. I've tried using this method but having the following error.
Unhandled Exception: type 'List' is not a subtype of type 'Map'
jsonResponse.body is supposed to be a string but it is reading it as List<dynamic>. Why is that happening? Am I doing anything wrong while parsing the result? Thanks
Here is a simple example created for you to understand how to do this. This is ok for small list but if you have a large list, I dont recommend this because of we are doing too much stuff here.
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Todo {
final String title;
final String description;
Todo(this.title, this.description);
Todo.fromJson(Map<String, dynamic> map) :
title = map["title"],
description = map["description"];
Map<String, dynamic> toMap() => {
"title": title,
"description": description
};
}
void main() {
runApp(MaterialApp(
title: 'Passing Data',
home: HomePage(
todos: List.generate(
20, (i) => Todo(
'Todo $i',
'A description of what needs to be done for Todo $i',
),
),
),
));
}
class HomePage extends StatelessWidget {
final List<Todo> todos;
HomePage({this.todos}) {
saveTodos();
}
void saveTodos() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List<String> values = todos.map((item) => json.encode(item.toMap())).toList();
prefs.setStringList("todos", values);
}
#override
Widget build(BuildContext context) {
return TodosScreen();
}
}
class TodosScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _StateTodosScreen();
}
}
class _StateTodosScreen extends State<TodosScreen> {
Future<List<Todo>> getTodos() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List<String> values = prefs.getStringList("todos");
return values.map((item) => Todo.fromJson(json.decode(item))).toList();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Todos'),
),
body: FutureBuilder(
future: getTodos(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(snapshot.data[index].title),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(todo: snapshot.data[index]),
),
);
},
);
},
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),
);
}
}
class DetailScreen extends StatelessWidget {
final Todo todo;
DetailScreen({Key key, #required this.todo}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Text(todo.description),
),
);
}
}
But you can simply encode your complete json and store, there will not be much work then, but if it is a complex json you have to handle that also.

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();
},
),
),
);
}
}