Why does my jsonDecode() method in Flutter throw a Format Exception? - json

I've been learning mobile development on Flutter for a while and currently trying to build a single-page text translation app, for exercise. I tried to integrate a Google Translate API.
I'm having trouble running the app due to an error (Format Exception) in the jsonDecode() method I use to extract the translation result json object (Post method HTTP request)
Here's my home screen code
import 'package:flutter/material.dart';
import '../models/input_model.dart';
class HomePage extends StatefulWidget {
HomePage({Key? key}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
TextEditingController textController = TextEditingController();
final translation = Sentence();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Translation App')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
////////////// Widget for the translation source text //////////////
Container(
width: MediaQuery.of(context).size.width / 1.5,
child: TextField(
controller: textController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(8)))),
)),
////////////////////////////////////////////////////////////////////
ElevatedButton(
onPressed: () {
Sentence.connectToAPI('en', 'de', textController.text); //static language option
setState(() {}); //input for testing
},
child: Text('Translate')),
////////////// Widget for the translation result text //////////////
Container(
width: MediaQuery.of(context).size.width / 1.5,
child: Text((translation.trans == null)
? 'no data'
: translation.trans.toString())),
],
),
),
);
}
}
And here's the model file where the problem lies:
import 'dart:convert';
import 'package:http/http.dart' as http;
class Sentence {
Sentence({
this.trans,
this.orig,
this.backend,
});
String? trans;
String? orig;
int? backend;
factory Sentence.fromJson(Map<String, dynamic> json) => Sentence(
trans: json["trans"],
orig: json["orig"],
backend: json["backend"],
);
Map<String, dynamic> toJson() => {
"trans": trans,
"orig": orig,
"backend": backend,
};
static Future<Sentence> connectToAPI(
String from, String to, String text) async {
String pathURL =
'https://translate.google.com/translate_a/single?client=at&dt=t&dt=ld&dt=qca&dt=rm&dt=bd&dj=1&ie=UTF-8&oe=UTF-8&inputm=2&otf=2&iid=1dd3b944-fa62-4b55-b330-74909a99969e';
var response =
await http.post(Uri.parse(pathURL), headers: <String, String>{
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'PostmanRuntime/7.29.0'
}, body: {
'sl': from,
'tl': to,
'q': text
});
var jsonObject = jsonDecode(response.body); //the exception error message pointed here
var textObject = (jsonObject as Map<String, dynamic>)['sentences'];
return Sentence.fromJson(textObject);
}
}
The exception error message was:
FormatException (FormatException: Unexpected character (at character 1)
^
I'm still a newbie and it really confuses me. I tried to search for the explanation of the error message on Google but still having a hard time understanding it. What seems to be the problem here?

Related

Flutter how to get specific value from json http response

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

How do I parse images from a json file using flutter in which my images are local?

I'm currently hard coding my images inside a list that takes in an imageUrl like this:
final slideList = [
Slide(imageUrl: 'assets/images/dog1.jpeg'),
Slide(imageUrl: 'assets/images/dog2.jpeg'),
Slide(imageUrl: 'assets/images/dog3.jpeg')
];
I have an assets folder with an images folder nested inside, as well as a json file. I'm trying to figure out how to parse the json so I can avoid hard coding every single image I'll have in the future in said list. The json file looks like this:
[
{
"images": [
"assets/images/dog1.jpeg",
"assets/images/dog2.jpeg",
"assets/images/dog3.jpeg"
]
}
]
The images I'm using are located inside of my images folder, therefore I'm not using an api to grab images from the web. I want to be able to parse the json file and store the images in the list in the above code snippet rather than hard coding 100 different imageUrl's.
Any help would be much appreciated!
Assuming you are using json given above your Slide class will look like this
class Slide {
String imageUrl;
Slide(this.imageUrl);
factory Slide.fromJson(dynamic json) {
return Slide(json['Image'] as String);
}
#override
String toString() {
return '{ ${this.imageUrl} }';
}
}
So to parse the json to the slide object you can use following code which will map JSON object to the Slide Object
void main() {
String jsonString = '[{"Image":"assets/images/dog1.jpeg"},{"Image":"assets/images/dog2.jpeg"},{"Image":"assets/images/dog3.jpeg"}]';
var mySlideJson = jsonDecode(jsonString) as List;
List<Slide> slideObjs = mySlideJson.map((slideJson) => Slide.fromJson(slideJson)).toList();
}
Hope this helps to achieve your goal.
You can copy paste run full code below
Step 1: parse with Payload class , you can see full code below
final payload = payloadFromJson(jsonString);
Step 2: use List<Slide>.generate
var slideList = new List<Slide>.generate(3, (i) {
return Slide(
imageUrl: payload[0].images[i],
);
});
output
I/flutter (10200): assets/images/dog1.jpeg
I/flutter (10200): assets/images/dog2.jpeg
I/flutter (10200): assets/images/dog3.jpeg
I/flutter (10200): [Instance of 'Slide', Instance of 'Slide', Instance of 'Slide']
I/flutter (10200): assets/images/dog1.jpeg
I/flutter (10200): assets/images/dog2.jpeg
I/flutter (10200): assets/images/dog3.jpeg
full code
import 'package:flutter/material.dart';
// To parse this JSON data, do
//
// final payload = payloadFromJson(jsonString);
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 {
List<String> images;
Payload({
this.images,
});
factory Payload.fromJson(Map<String, dynamic> json) => Payload(
images: List<String>.from(json["images"].map((x) => x)),
);
Map<String, dynamic> toJson() => {
"images": List<dynamic>.from(images.map((x) => x)),
};
}
class Slide {
final String imageUrl;
Slide({this.imageUrl});
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
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 = '''
[
{
"images": [
"assets/images/dog1.jpeg",
"assets/images/dog2.jpeg",
"assets/images/dog3.jpeg"
]
}
]
''';
void _incrementCounter() {
final payload = payloadFromJson(jsonString);
print( payload[0].images[0] );
print( payload[0].images[1] );
print( payload[0].images[2] );
var slideList = new List<Slide>.generate(3, (i) {
return Slide(
imageUrl: payload[0].images[i],
);
});
print(slideList.toString());
print(slideList[0].imageUrl);
print(slideList[1].imageUrl);
print(slideList[2].imageUrl);
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.display1,
),
],
),
),
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(),
),
),
),
],
),
),
);
}
}

How to deal with complex API responses for making cards in Flutter?

I am very new to Flutter and now developing an app that lists restaurants.
I have an API endpoint that returns JSON data. Here it is: https://node.coredes.in/restaurants.
I have already done the layouts. But I don't know how to deal with JSON data. I already tried to do this from examples I got from net.
I want to know how can I use these fields - doc.name, doc.image_gallery[0], doc.location.locality, doc.friday.closing_at.hour, doc.friday.closing_at.minute, to make a list of cards?
Could anyone please help me out with a sample code?
Here is a sample code below, shows how to get the name of restaurants in your JSON file:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
void main() {
runApp(new MaterialApp(
home: new HomePage(),
));
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
String url = "https://node.coredes.in/restaurants/";
List data;
/*onCreate*/
#override
void initState() {
// TODO: implement initState
super.initState();
getJSONData(); //method
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(title: Text("my JSON app")),
body: new ListView.builder(
// itemCount: 1,
//itemCount: data==null ? 0 :data.length ,
itemCount: data == null ? 0 : data.length,
itemBuilder: (BuildContext context, int index) {
return new Container(
child: new Center(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Card(
child: new Container(
child: new Text(data[index]['name'] ?? ''),
padding: EdgeInsets.all(20),
),
)
],
),
),
);
},
),
);
}
/*method*/ //RT is Future<String>
Future<String> getJSONData() async {
var response = await http
.get(Uri.encodeFull(url), headers: {"Accept": "application/json"});
print(response.body);
debugPrint(response.body);
setState(() {
var convertDataToJson = json.decode(response.body);
data = convertDataToJson['doc'];
});
return "Success";
}
}
And you can play with data[index]['name']. For example if you want the city you can do something like that data[index]['location']['city'].
So the class model you said, is in order to make your code easy to understand and fast to be reused. Your JSON file have a complex embedded data on it, and it's a little difficult to access this data. So using a class model will be very helpful to get easily, whatever the value you want from it. Let me show you that with a concret example, to know when a restaurant will open and close, you need to go along with this hierarchy doc => opening_times => Sunday => opening_at and the same for the closing time. So let's translate it to our flutter code, if we want to get just the hour value, it will be like data[index]['opening_time']['Sunday']['opening_at']['hour'], and the same for minute value, same for all the rest. In this hierarchy we didn't took so long to arrive to the end, but you're free to imagine in a very big hierarchy, how it will be the situation. Let's return to our case, now let's take the same example and try to use, like you said, a class model instead of a hard coded JSON attributs. Let's write a model class for Restaurant.
class Restaurant {
String name;
String city;
String day;
bool isOpen;
int hourOpen;
int minuteOpen;
// ..
// ..
// The rest of your wanted attributs
Restaurant(
{this.name,
this.city,
this.day,
this.isOpen,
this.hourOpen,
this.minuteOpen});
}
After that, we will write a method, its main goal is to fill our restaurants variable.
Future<String> getRestaurants() async {
var response = await http
.get(Uri.encodeFull(url), headers: {"Accept": "application/json"});
var convertDataToJson = json.decode(response.body);
data = convertDataToJson['doc'];
List tempRestaurants = new List();
data.forEach((restaurant) => {
tempRestaurants.add(new Restaurant(
name: restaurant['name'],
city: restaurant['location']['city'],
day: 'Sunday',
isOpen: restaurant['opening_times']['Sunday']['is_open_today'],
hourOpen: restaurant['opening_times']['Sunday']['opening_at']
['hour'],
minuteOpen: restaurant['opening_times']['Sunday']['opening_at']
['minute'])),
});
setState(() {
this.restaurants = tempRestaurants;
});
}
Here is how we get data after writing the model.
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(title: Text("my JSON app")),
body: new ListView.builder(
itemCount: restaurants == null ? 0 : restaurants.length,
itemBuilder: (BuildContext context, int index) {
return new Container(
child: new Center(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Card(
child: new Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("Name: ${restaurants[index].name}"),
Text("City: ${restaurants[index].city}"),
Text("Day: ${restaurants[index].day}"),
Text("IsOpen: ${restaurants[index].isOpen}"),
Text(
"Time: ${restaurants[index].hourOpen}:${restaurants[index].minuteOpen}"),
]),
padding: EdgeInsets.all(20),
),
)
],
),
),
);
},
),
);
}
PS: in this example, I just took Sunday value in every restaurant instance, so that I can show you how easily the access to data has become. But you can create a class model for it, let's say RestaurantDay, and have attributs like dayName, hourOpen, minuteOpen... And after that, you can link it with the logic where we get data.
Try this:
class DemoClass {
String name;
int Id;
DemoClass(this.name, this.Id);
static DemoClass fromJson(Map<String, dynamic> json) {
return DemoClass(json['name'] as String, json['Id'] as int);
}
Map<String, dynamic> toJson(DemoClass instance) =>
<String, dynamic>{
'name': instance.name,
'Id': instance.trackerId
};
static List<DemoClass> fromJsonListStr(String jsonStr){
var list = jsonDecode(jsonStr) as List;
List<DemoClass> myThing = list.map((e) => DemoClass.fromJson(e)).toList();
return myThing;
}
}
Use this to get a list of objects:
var resp = await http.get('http://apicall.com/array',
headers: {"Content-Type": "application/json"});
var ret = DemoClass.fromJsonListStr(resp.body);
return ret;
Use this to get a single object:
var resp = await http.get('http://apicall.com/array',
headers: {"Content-Type": "application/json"});
var data = jsonDecode(resp.body);
var obj = DemoClass.fromJson(data);

Flutter doesn't want to import json

I am trying to follow this official tutorial in order to make a web request to an url: https://flutter.io/cookbook/networking/fetch-data/
I have thus added these lines in pubspec.yaml:
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
http: 0.11.3+17
json_annotation: ^0.2.3
dev_dependencies:
flutter_test:
sdk: flutter
build_runner: ^0.9.0
json_serializable: ^0.5.4
and when compiling, I got this error.
Compiler message: lib/main.dart:53:26: Error: Method not found:
'decode'.
return Post.fromJson(json.decode(response.body));
Any idea what I am doing wrong?
Here is my code:
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo2',
theme: new ThemeData(
primarySwatch: Colors.amber,
),
home: new MyHomePage(title: 'Islam Essentiel'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class Post {
final int userId;
final int id;
final String title;
final String body;
Post({this.userId, this.id, this.title, this.body});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
userId: json['userId'],
id: json['id'],
title: json['title'],
body: json['body'],
);
}
}
Future<Post> fetchPost() async {
final response =
await http.get('https://jsonplaceholder.typicode.com/posts/1');
if (response.statusCode == 200) {
// If server returns an OK response, parse the JSON
return Post.fromJson(json.decode(response.body));
} else {
// If that response was not OK, throw an error.
throw Exception('Failed to load post');
}
}
class _MyHomePageState extends State<MyHomePage> {
void _incrementCounter() {
setState(() {
});
}
#override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return new Scaffold(
appBar: new AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: new Text(widget.title),
),
body: new Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: new Column(
// Column is also layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Invoke "debug paint" (press "p" in the console where you ran
// "flutter run", or select "Toggle Debug Paint" from the Flutter tool
// window in IntelliJ) to see the wireframe for each widget.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Card(
child: new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const ListTile(
leading: const Icon(Icons.album),
title: const Text('al-khamis: 30. Muharram 1440'),
subtitle: const Text('20:51 - Icha.'),
),
new ButtonTheme.bar( // make buttons use the appropriate styles for cards
child: new ButtonBar(
children: <Widget>[
new FlatButton(
child: const Text('MECQUE - DIRECTION'),
onPressed: () { /* ... */ },
),
],
),
),
],
),
),
],
),
),
floatingActionButton: new FloatingActionButton(
onPressed: fetchPost,
tooltip: 'Increment',
child: new Icon(Icons.add),
),
);
}
}
You need to import it
import 'dart:convert' show jsonDecode;
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
...
and use it with
jsonDecode(response.body)
or
import 'dart:convert' show json;
with
json.decode(response.body)
The first variant was added to avoid conflicts when the variable holding the JSON value is named json.