Flutter how to get specific value from json http response - json

I am using this code to upload json data to my nodejs server.
HttpClient client = new HttpClient();
var data = createSamplePayment().toJson();
var request = await client.openUrl('POST', Uri.parse(serverEndpoint + '/paymentrequests'));
request.headers.set(HttpHeaders.contentTypeHeader, 'APPLICATION/JSON');
request.write(json.encode(data));
var response = await request.close();
String reply = await response.transform(utf8.decoder).join();
print(reply);
The output from print(reply) is:
flutter: {"url":"https://paymentrequests/86C0110D","token":"w8SWavZNjOG","id":"C3C4966AF64D8CE194F5E3C"}
But I only want to get ”token” value. What can I do to fix that? I have tried in many different ways without success.

class DetailsModel {
String url;
String token;
String id;
DetailsModel({this.url, this.token, this.id});
DetailsModel.fromJson(Map<String, dynamic> json) {
url = json['url'];
token = json['token'];
id = json['id'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['url'] = this.url;
data['token'] = this.token;
data['id'] = this.id;
return data;
}
}
Firstly, convert your response into a Model, to do that you would need the above code. Then map your response.
DetailsModel details = DetailsModel.fromJson(response);
Then to access the details you can simply use.
dynamic token = details.token;
print(token); // w8SWavZNjOG

You can copy paste run full code below
I use the following code to simulate this case
You can do payloadFromJson(reply) and return payload.token
You can reference Payload class in full code
code snippet
Payload payloadFromJson(String str) => Payload.fromJson(json.decode(str));
...
Future<String> postWithClientCertificate() async {
...
Payload payload = payloadFromJson(reply);
print(payload.token);
return payload.token;
}
output
I/flutter ( 5995): w8SWavZNjOG
I/flutter ( 5995): token w8SWavZNjOG
full code
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'dart:convert';
Payload payloadFromJson(String str) => Payload.fromJson(json.decode(str));
String payloadToJson(Payload data) => json.encode(data.toJson());
class Payload {
Payload({
this.url,
this.token,
this.id,
});
String url;
String token;
String id;
factory Payload.fromJson(Map<String, dynamic> json) => Payload(
url: json["url"],
token: json["token"],
id: json["id"],
);
Map<String, dynamic> toJson() => {
"url": url,
"token": token,
"id": id,
};
}
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;
void _incrementCounter() async{
String token = await postWithClientCertificate();
print("token $token");
setState(() {
_counter++;
});
}
Future<String> postWithClientCertificate() async {
/*final serverEndpoint = 'https://1991269db78887f9e.ngrok.io';
HttpClient client = new HttpClient();
var data = createSamplePayment().toJson();
var request = await client.openUrl('POST', Uri.parse(serverEndpoint + '/paymentrequests'));
request.headers.set(HttpHeaders.contentTypeHeader, 'APPLICATION/JSON');
request.write(json.encode(data));
var response = await request.close();
String reply = await response.transform(utf8.decoder).join();
print(reply);*/
String reply =
'''{"url":"https://paymentrequests/86C0110D","token":"w8SWavZNjOG","id":"C3C4966AF64D8CE194F5E3C"}''';
Payload payload = payloadFromJson(reply);
print(payload.token);
return payload.token;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

Related

Flutter - Errors when trying to save JSON Array to List

I am new to flutter and trying to fetch API data into a list. My goal is to later input that information into a ListView.
I am familiar with doing api calls but now I'm triying to get information from a json array. Previously I made a model class to retrieve the objects I need to continue with my process, but I've reached a dead end since I can't seem to figure out how to extract the objects from an array properly.
I am using multiple files. "API Services", "readData Model", and the actual screen where the data will be shown.
Everything else is fine, it's just that I am unable to actually save the data to a list.
First I will show you how my code is set up and the JSON response data I am trying to save:
JSON Response Body:
The example I am showing only has one chunk of image data, but we need an array for it since it should be displaying every chunk in a list.
{"status":200,
"content":[{"image_id":"151",
"image_url":"https:\\\/imageurl.jpg",
"returned_value":"14.0",
"alarm":"false",
"account":"test#email.com",
"create_at":"2020-11-17 07:13:42",
"location":"NY"
}]
}
API POST function:
Future<ReadResponseModel> readData(
ReadRequestModel requestData) async {
final response = await http.post("$url/read",
body: requestData.toJson() ,
headers: {
"Client-Service": "frontend-client",
"Auth-Key": "simplerestapi",
"Content-Type":"application/x-www-form-urlencoded",
"Authorization": token,
"User-ID": userId,
});
print(response.body);
if (response.statusCode == 200 || response.statusCode == 400) {
dynamic resBody = json.decode(response.body);
return ReadResponseModel.fromJson(resBody);
} else {
throw Exception('Failed to load data!');
}
}
readResponseModel Class:
I have tried two methods to process this information but have failed at both of them.
This is Method 1:
This one will give me the following error: [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'
Originally set as final String for all values, but since I was getting this error I've been trying to make sure each one is the correct type (ex. retVal as int or alarm as bool). Still no luck so far.
class ReadResponseModel {
final dynamic imageID;
final dynamic imgUrl;
final dynamic retVal;
final bool alarm;
final dynamic account;
final dynamic createAt;
final dynamic location;
ReadResponseModel({this.imageID, this.imgUrl, this.retVal, this.alarm,
this.account, this.createAt, this.location,});
factory ReadResponseModel.fromJson(Map<String , dynamic> json) {
return ReadResponseModel(
imageID: json['content']['image_id'] as String ,
imgUrl: json['content']['image_url'] as String ,
retVal: json['content']["returned_value"] as String,
alarm: json['content']['alarm'] as bool ,
account: json['content']['account'] as String,
createAt: json['content']['create_at'] as String,
location: json['content']['location'] as String,
);
}
}
Method 2:
This one will give me the following error:
[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: type '(dynamic) => Content' is not a subtype of type '(dynamic) => String' of 'f' -- I dont even know where that f came from.
class ReadResponseModel {
List<String> content;
ReadResponseModel({this.content});
factory ReadResponseModel.fromJson(Map<String, dynamic> json) {
return ReadResponseModel(
content: json['content'] != null
? json['content']
.map<String>((json) => Content.fromJson(json))
.toList()
: null,
);
}
}
class Content {
final String imageID;
final String imgUrl;
final String retVal;
final String alarm;
final String account;
final String createAt;
final String location;
final String error;
Content({this.imageID,
this.imgUrl,
this.retVal,
this.alarm,
this.account,
this.createAt,
this.location,
this.error});
factory Content.fromJson(Map<String, dynamic> json) =>
Content(
imageID: json['image_id'],
imgUrl: json['s3_url'],
retVal: json['predict'],
alarm: json['alarm'],
account: json['account'],
createAt: json['create_at'],
location: json['location'],
);
}
The following code is just what I'm doing to connect all this to my widget:
APIService readService = new APIService();
readRequestModel.companyID = "123";
readService.readData(readRequestModel).then((value) async {
if (value != null) {
setState(() {
isApiCallProcess = false;
});
///Trying to call the fetched data and show it in the console:
print("Account: ${value.account}");
print("Returned Value: ${value.retVal}");
print("Image ID: ${value.imgUrl}");
}
I'm not entirely sure why I am getting these errors, and for method 2 I don't even know where that "f" came from. If anyone could shed some light on the subject it would be greatly appreciated.
You can copy paste run full code below
Step 1: Use List<Content> content; not List<String>
Step 2: Use List<Content>.from(json["content"].map((x) => Content.fromJson(x)))
Step 3: In sample JSON's image_url not equal model's s3_url, you need to modify to correct one
code snippet
class ReadResponseModel {
List<Content> content;
ReadResponseModel({this.content});
factory ReadResponseModel.fromJson(Map<String, dynamic> json) {
return ReadResponseModel(
content: json['content'] != null
? List<Content>.from(json["content"].map((x) => Content.fromJson(x)))
: null,
);
}
}
...
dynamic resBody = json.decode(jsonString);
ReadResponseModel model = ReadResponseModel.fromJson(resBody);
print(model.content[0].account);
output
I/flutter ( 4426): test#email.com
full code
import 'package:flutter/material.dart';
import 'dart:convert';
class ReadResponseModel {
List<Content> content;
ReadResponseModel({this.content});
factory ReadResponseModel.fromJson(Map<String, dynamic> json) {
return ReadResponseModel(
content: json['content'] != null
? List<Content>.from(json["content"].map((x) => Content.fromJson(x)))
: null,
);
}
}
class Content {
final String imageID;
final String imgUrl;
final String retVal;
final String alarm;
final String account;
final String createAt;
final String location;
final String error;
Content(
{this.imageID,
this.imgUrl,
this.retVal,
this.alarm,
this.account,
this.createAt,
this.location,
this.error});
factory Content.fromJson(Map<String, dynamic> json) => Content(
imageID: json['image_id'],
imgUrl: json['s3_url'],
retVal: json['predict'],
alarm: json['alarm'],
account: json['account'],
createAt: json['create_at'],
location: json['location'],
);
}
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;
void _incrementCounter() {
String jsonString = '''
{"status":200,
"content":[{"image_id":"151",
"image_url":"https:\\\/imageurl.jpg",
"returned_value":"14.0",
"alarm":"false",
"account":"test#email.com",
"create_at":"2020-11-17 07:13:42",
"location":"NY"
}]
}
''';
dynamic resBody = json.decode(jsonString);
ReadResponseModel model = ReadResponseModel.fromJson(resBody);
print(model.content[0].account);
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
From the above mentioned code I have created a sample example for you, basically you are messing up with the mode class.Take a look at the example below.
Json you provided:
{"status":200,
"content":[{"image_id":"151",
"image_url":"https:\\\/imageurl.jpg",
"returned_value":"14.0",
"alarm":"false",
"account":"test#email.com",
"create_at":"2020-11-17 07:13:42",
"location":"NY"
}]
}
Based on the json the model class below :
// To parse this JSON data, do
//
// final readResponseModel = readResponseModelFromJson(jsonString);
import 'dart:convert';
ReadResponseModel readResponseModelFromJson(String str) => ReadResponseModel.fromJson(json.decode(str));
String readResponseModelToJson(ReadResponseModel data) => json.encode(data.toJson());
class ReadResponseModel {
ReadResponseModel({
this.status,
this.content,
});
int status;
List<Content> content;
factory ReadResponseModel.fromJson(Map<String, dynamic> json) => ReadResponseModel(
status: json["status"],
content: List<Content>.from(json["content"].map((x) => Content.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"content": List<dynamic>.from(content.map((x) => x.toJson())),
};
}
class Content {
Content({
this.imageId,
this.imageUrl,
this.returnedValue,
this.alarm,
this.account,
this.createAt,
this.location,
});
String imageId;
String imageUrl;
String returnedValue;
String alarm;
String account;
DateTime createAt;
String location;
factory Content.fromJson(Map<String, dynamic> json) => Content(
imageId: json["image_id"],
imageUrl: json["image_url"],
returnedValue: json["returned_value"],
alarm: json["alarm"],
account: json["account"],
createAt: DateTime.parse(json["create_at"]),
location: json["location"],
);
Map<String, dynamic> toJson() => {
"image_id": imageId,
"image_url": imageUrl,
"returned_value": returnedValue,
"alarm": alarm,
"account": account,
"create_at": createAt.toIso8601String(),
"location": location,
};
}
And them main class for fetching the data and showing it in the listview.
import 'package:flutter/material.dart';
import 'package:json_parsing_example/model2.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: SampleApp(),
debugShowCheckedModeBanner: false,
);
}
}
class SampleApp extends StatefulWidget {
#override
_SampleAppState createState() => _SampleAppState();
}
class _SampleAppState extends State<SampleApp> {
bool _isLoading = false;
List<Content> list = List();
fetchData() async {
setState(() {
_isLoading = true;
});
String data =
await DefaultAssetBundle.of(context).loadString("json/parse.json");
// This is the above where you get the remote data
// Like var response = await get or post
final readResponseModel = readResponseModelFromJson(data);
list = readResponseModel.content;
setState(() {
_isLoading = false;
});
}
#override
void initState() {
super.initState();
fetchData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Your heading'),
),
body: Container(
child: _isLoading
? Center(child: CircularProgressIndicator())
: Column(
children: <Widget>[
ListView.builder(
shrinkWrap: true,
itemCount: list.length,
itemBuilder: (context, index) {
return Card(
child: Column(
children: <Widget>[
Text('${list[index].account}'),
Text('${list[index].location}')
],
),
);
})
],
)));
}
}
Let me know if it works
Can you try setting returned_value and image_id as int instead of string and give it a try ?

How to parse JSON in flutter when the reponse is an array of objects

I am getting an API response of the following type
[
{"name":"lakshay","id":"1217","type":"Staff","temperature":56.6,"date":"12-06-2020"},
{"name":"lakshay","id":"1217","type":"Staff","temperature":56.6,"date":"12-06-2020"},
.....
]
I need to parse the whole thing as List of objects, so that I can do something like
// conceptual //
array.map((obj)=>{
// computation //
})
I took help from here but it doesn't tell how to parse the outer array.
thanks for your time.
You can generate expected response class online using below link and create and save class in your project :
https://javiercbk.github.io/json_to_dart/
For more details see this image :
class ApiRepositary {
Dio dio;
ApiRepositary() {
if (dio == null) {
BaseOptions options = new BaseOptions(
baseUrl: "your base url",
receiveDataWhenStatusError: true,
connectTimeout: 60*1000, // 60 seconds
receiveTimeout: 60*1000 // 60 seconds
);
dio = new Dio(options);
}
}
Future<List<UserResponse>> getUserDetails() async {
try {
Response res = await dio.get("/lookup/pollquestion/add your url here");
if (res.data.toString().isEmpty) {
throw Exception();
} else {
final List rawData = jsonDecode(jsonEncode(res.data));
List<UserResponse> response =
rawData.map((f) => UserResponse.fromJson(f)).toList();
return response;
}
} on DioError catch (dioError) {
throw Exception(dioError);
}
}
}
To call service in your class :
ApiRepositary().getUserDetails().then((response){
debugPrint("Login Success $response");
//manage your response here, here you will get arralist as a response
},
onError: (exception){
//Handle exception message
if(exception.message != null ){
debugPrint(exception.message);
}
},
);
You can copy paste run full code below
Step 1: parse with List<Payload> payloadList = payloadFromJson(jsonString); , you can see full code for detail Payload class definition
Step 2: For loop like this
payloadList.forEach((element) {
print(element.name);
print(element.id);
});
output
I/flutter (17660): lakshay
I/flutter (17660): 1217
I/flutter (17660): lakshay
I/flutter (17660): 1217
full code
import 'package:flutter/material.dart';
import 'dart:convert';
List<Payload> payloadFromJson(String str) =>
List<Payload>.from(json.decode(str).map((x) => Payload.fromJson(x)));
String payloadToJson(List<Payload> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Payload {
Payload({
this.name,
this.id,
this.type,
this.temperature,
this.date,
});
String name;
String id;
String type;
double temperature;
String date;
factory Payload.fromJson(Map<String, dynamic> json) => Payload(
name: json["name"],
id: json["id"],
type: json["type"],
temperature: json["temperature"].toDouble(),
date: json["date"],
);
Map<String, dynamic> toJson() => {
"name": name,
"id": id,
"type": type,
"temperature": temperature,
"date": date,
};
}
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;
String jsonString = '''
[
{"name":"lakshay","id":"1217","type":"Staff","temperature":56.6,"date":"12-06-2020"},
{"name":"lakshay","id":"1217","type":"Staff","temperature":56.6,"date":"12-06-2020"}
]
''';
void _incrementCounter() {
List<Payload> payloadList = payloadFromJson(jsonString);
payloadList.forEach((element) {
print(element.name);
print(element.id);
});
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
Please use this response class
class YourResponse {
String name;
String id;
String type;
double temperature;
String date;
YourResponse({this.name, this.id, this.type, this.temperature, this.date});
YourResponse.fromJson(Map<String, dynamic> json) {
name = json['name'];
id = json['id'];
type = json['type'];
temperature = json['temperature'];
date = json['date'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['id'] = this.id;
data['type'] = this.type;
data['temperature'] = this.temperature;
data['date'] = this.date;
return data;
}
}
Assuming
String jsonResponse = '''[
{"name":"lakshay","id":"1217","type":"Staff","temperature":56.6,"date":"12-06-2020"},
{"name":"lakshay","id":"1217","type":"Staff","temperature":56.6,"date":"12-06-2020"}
]''';
You could do something as below:
Step 1) import 'dart:convert' package.
Step 2 ) Add following lines:
List<dynamic> responses = jsonDecode(jsonResponse);
responses.forEach((obj){
print(obj['name']);
});
Remember the above code is a quick & dirty way get things working.you may lose many benefits of static type checking.It always recommended that use classes created as suggested by chunhunghan.

Convert Json Array to List<Object> in Flutter

I'm new to Flutter and Dart and I have been struggling with saving values in shared preferences to use when my app is restarted. I have successfully stored variables, but I also need object lists to be stored. I know that since shared preferences only accept String lists, I need to convert my object list into a JSON array and when the app is restarted, retrieve this list and convert it to an object list again.
I was able to encode the object list to JSON and I got something like this:
[{name: Rent, amount: 250}, {name: Insurance, amount: 105}]
I achieved this with the following function:
void SaveLists(key, value) async { //where value is a List<Object>
final prefs = await SharedPreferences.getInstance();
List<dynamic> json_list = (value.map((i) => i.toJson())).toList();
prefs.setStringList(key, json_list); //this line causes the error
print('$json_list');
}
The List json_list contains the JSON array that is shown above. However when I try to store it in the shared preferences with prefs.setStringList(key, json_list); I get the following error:
Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'List<String>'
Now, let's say that I somehow store it successfully in shared preferences, how do I convert the JSON array back to a List when called with prefs.getString('key')?
In case you need to see the class, here it is:
import 'dart:convert';
class Random_expenses {
String name;
double amount;
Random_expenses({this.name, this.amount});
Random_expenses.fromJson(Map<String, dynamic> json)
: this.name = json['name'],
this.amount = json['amount'];
Map<String, dynamic> toJson() =>
{'name': this.name, 'amount': this.amount};
}
You can copy paste run full code below
You can save List<RandomExpenses> as a json string with randomExpensesToJson(value)
You can get List<RandomExpenses> with randomExpensesFromJson(keyString)
code snippet
List<RandomExpenses> randomExpensesFromJson(String str) =>
List<RandomExpenses>.from(
json.decode(str).map((x) => RandomExpenses.fromJson(x)));
String randomExpensesToJson(List<RandomExpenses> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
...
void saveData(String key, List<RandomExpenses> value) async {
final prefs = await SharedPreferences.getInstance();
prefs.setString(key, randomExpensesToJson(value));
}
Future<List<RandomExpenses>> getData(String key) async {
final prefs = await SharedPreferences.getInstance();
String keyString = prefs.getString(key);
return Future.value(randomExpensesFromJson(keyString));
}
...
await saveData("key", randomExpensesList);
List<RandomExpenses> list = await getData("key");
print('${list[0].name} ${list[0].amount}');
print('${list[1].name} ${list[1].amount}');
output
I/flutter (24879): Rent 250
I/flutter (24879): Insurance 105
full code
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
List<RandomExpenses> randomExpensesFromJson(String str) =>
List<RandomExpenses>.from(
json.decode(str).map((x) => RandomExpenses.fromJson(x)));
String randomExpensesToJson(List<RandomExpenses> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class RandomExpenses {
String name;
int amount;
RandomExpenses({
this.name,
this.amount,
});
factory RandomExpenses.fromJson(Map<String, dynamic> json) => RandomExpenses(
name: json["name"],
amount: json["amount"],
);
Map<String, dynamic> toJson() => {
"name": name,
"amount": amount,
};
}
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;
List<RandomExpenses> randomExpensesList = [
RandomExpenses(name: "Rent", amount: 250),
RandomExpenses(name: "Insurance", amount: 105)
];
void saveData(String key, List<RandomExpenses> value) async {
final prefs = await SharedPreferences.getInstance();
prefs.setString(key, randomExpensesToJson(value));
}
Future<List<RandomExpenses>> getData(String key) async {
final prefs = await SharedPreferences.getInstance();
String keyString = prefs.getString(key);
return Future.value(randomExpensesFromJson(keyString));
}
void _incrementCounter() async {
await saveData("key", randomExpensesList);
List<RandomExpenses> list = await getData("key");
print('${list[0].name} ${list[0].amount}');
print('${list[1].name} ${list[1].amount}');
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

Flutter populate dropdown with Json response, using dio plugin for server call

Getting below Format exception when I am trying to decode Json response. Please help out.
Unhandled Exception: FormatException: Unexpected character (at character 3)
[{table_no: 1}, {table_no: 2}, {table_no: 3}]
[
{
"table_no": "1"
},
{
"table_no": "2"
},
{
"table_no": "3"
}
]
Future<Response> pos_client_table() async {
String url =
'https://xxxxxx.com/api/v1/table?branch_id=1';
Response response;
Dio dio = new Dio();
dio.options.headers = {'Authorization': prefs.getString('posclient_token')};
try {
response = await dio.get(url);
var jso = json.decode(response.toString());
Fluttertoast.showToast(
msg: "$jso",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIos: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
} catch (e) {
print(e);
}
return response;
}
void CallTableUrl() async {
Response response = await pos_client_table();
List<Map> _myJson = json.decode(response.toString());
showInSnackBar('$_myJson');
}
Edit add dio parse example and parse picture
Response response;
Dio dio = new Dio();
response = await dio.get("http://yoursite");
print(response);
print(response.data.toString());
List<Payload> payload = payloadFromJson(response.data);
print({payload[0].tableNo});
Assume dio already return correct json string is
String jsonString = '[{"table_no": "1"},{"table_no": "2"},{"table_no": "3"}]';
Step 1: Parse jsonString with payload class
List<Payload> payload = payloadFromJson(jsonString);
payload class
List<Payload> payloadFromJson(String str) =>
List<Payload>.from(json.decode(str).map((x) => Payload.fromJson(x)));
String payloadToJson(List<Payload> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Payload {
String tableNo;
Payload({
this.tableNo,
});
factory Payload.fromJson(Map<String, dynamic> json) => Payload(
tableNo: json["table_no"],
);
Map<String, dynamic> toJson() => {
"table_no": tableNo,
};
}
Step 2: transfer this payload to required map of DropdownMenuItem
for (var i = 0; i < payload.length; i++) {
_myJson.add({'id': payload[i].tableNo, 'name': payload[i].tableNo});
}
Step 3: populate DropdownMenuItem
DropdownButton<String>(
isDense: true,
hint: Text("${payload[0].tableNo}"),
value: _mySelection,
onChanged: (String Value) {
setState(() {
_mySelection = Value;
});
print(_mySelection);
},
items: _myJson.map((Map map) {
return DropdownMenuItem<String>(
value: map["id"].toString(),
child: Text(
map["name"],
),
);
}).toList(),
),
full code
import 'package:flutter/material.dart';
import 'dart:convert';
List<Payload> payloadFromJson(String str) =>
List<Payload>.from(json.decode(str).map((x) => Payload.fromJson(x)));
String payloadToJson(List<Payload> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Payload {
String tableNo;
Payload({
this.tableNo,
});
factory Payload.fromJson(Map<String, dynamic> json) => Payload(
tableNo: json["table_no"],
);
Map<String, dynamic> toJson() => {
"table_no": tableNo,
};
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
String jsonString = '[{"table_no": "1"},{"table_no": "2"},{"table_no": "3"}]';
List<Payload> payload = payloadFromJson(jsonString);
List<Map> _myJson = [];
class _MyHomePageState extends State<MyHomePage> {
String _mySelection;
#override
void initState() {
for (var i = 0; i < payload.length; i++) {
_myJson.add({'id': payload[i].tableNo, 'name': payload[i].tableNo});
}
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: <Widget>[
Container(
height: 500.0,
child: Center(
child: DropdownButton<String>(
isDense: true,
hint: Text("${payload[0].tableNo}"),
value: _mySelection,
onChanged: (String Value) {
setState(() {
_mySelection = Value;
});
print(_mySelection);
},
items: _myJson.map((Map map) {
return DropdownMenuItem<String>(
value: map["id"].toString(),
child: Text(
map["name"],
),
);
}).toList(),
),
),
),
],
),
),
);
}
}

can't fetch data api url json flutter

i try to fetch api json id , username , photo ..etc...
and when use jsonplaceholder it's working fine
and when use mine don't get any data
flutter code
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class ListViewJsonapi extends StatefulWidget {
_ListViewJsonapiState createState() => _ListViewJsonapiState();
}
class _ListViewJsonapiState extends State<ListViewJsonapi> {
final String uri = 'https://www.christian-dogma.com/android-index.php';
Future<List<Users>> _fetchUsers() async {
var response = await http.get(uri);
if (response.statusCode == 200) {
final items = json
.decode(utf8.decode(response.bodyBytes))
.cast<Map<String, dynamic>>();
List<Users> listOfUsers = items.map<Users>((json) {
return Users.fromJson(json);
}).toList();
return listOfUsers;
} else {
throw Exception('Failed to load internet');
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<List<Users>>(
future: _fetchUsers(),
builder: (context, snapshot) {
if (!snapshot.hasData)
return Center(child: CircularProgressIndicator());
return ListView(
children: snapshot.data
.map((user) => ListTile(
title: Text(user.name),
subtitle: Text(user.email),
leading: CircleAvatar(
backgroundColor: Colors.red,
child: Text(user.name[0],
style: TextStyle(
fontSize: 18.0,
color: Colors.white,
)),
),
))
.toList(),
);
},
),
);
}
}
class Users {
int id;
String name;
String username;
String email;
Users({
this.id,
this.name,
this.username,
this.email,
});
factory Users.fromJson(Map<String, dynamic> json) {
return Users(
id: json['id'],
name: json['name'],
email: json['email'],
username: json['username'],
);
}
}
when use https://jsonplaceholder.typicode.com/users it's working fine
and when use mine https://www.christian-dogma.com/android-index.php i don't get any data
He managed to make it work, one of the problems he has is that the id asks me to be a String since you had it as an integer, I hope it worked for you.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class JsonApiPhp extends StatefulWidget {
#override
_JsonApiPhpState createState() => _JsonApiPhpState();
}
class _JsonApiPhpState extends State<JsonApiPhp> {
bool loading = true;
final String url = 'https://www.christian-dogma.com/android-index.php';
var client = http.Client();
List<User> users = List<User>();
#override
void initState(){
fetchData();
super.initState();
}
Future<void> fetchData() async {
http.Response response = await client.get(url);
if(response.statusCode == 200){ // Connection Ok
List responseJson = json.decode(response.body);
responseJson.map((m) => users.add(new User.fromJson(m))).toList();
setState(() {
loading = false;
});
} else {
throw('error');
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
child: loading ?
Container(
child: Center(
child: CircularProgressIndicator(),
),
) :
ListView.builder(
itemCount: users.length,
itemBuilder: (BuildContext context, int index){
return Card(
child: ListTile(
title: Text(users[index].username),
),
);
},
)
),
);
}
}
class User {
final String id;
final String name;
final String username;
final String email;
User({
this.id,
this.name,
this.username,
this.email,
});
factory User.fromJson(Map<String, dynamic> json) {
return User(
id: json['id'],
name: json['name'],
email: json['email'],
username: json['username'],
);
}
}
I kind of banged my head around and finally found out that your JSON response is returning the id as a string and not as an integer.
Change the factory to following code.
factory Users.fromJson(Map<String, dynamic> json) {
return Users(
id: int.parse(json['id']),
name: json['name'],
email: json['email'],
username: json['username'],
);
Cheers!