I have a php file hosted on my college server and when i run this file on the server it works very well. I can get the json data after running my php file which is in the link http://www.alkadhum-col.edu.iq/Teachers%20Activities/get.php but when i was unable to got them when i had tried that in flutter on the app screen got "the getter 'length'was called on null".
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
void main() {
runApp(Workshops());
}
class Workshops extends StatelessWidget {
#override
Widget build(BuildContext mycontext) {
return MaterialApp(
home:Scaffold(
appBar: AppBar(
backgroundColor: Color.fromRGBO( 52, 73, 94, 1.0),
automaticallyImplyLeading: false, // Don't show the leading button
title: new Text("PHP with Flutter"),
),
body: PostScreen(),
)
);
}
}
class PostScreen extends StatefulWidget {
#override
_PostScreenState createState() => _PostScreenState();
}
class _PostScreenState extends State<PostScreen> {
List<Post> _postList = new List<Post>();
Future<List<Post>> fetchPost() async {
final response =
await http.get('http://www.alkadhum-col.edu.iq/Teachers%20Activities/get.php');
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON
List<dynamic> values = new List<dynamic>();
values = json.decode(response.body);
if (values.length > 0) {
for (int i = 0; i < values.length; i++) {
if (values[i] != null) {
Map<String, dynamic> map = values[i];
_postList.add(Post.fromJson(map));
}
}
}
return _postList;
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
#override
Widget build(BuildContext context) {
return FutureBuilder<List<Post>>(
future: fetchPost(),
builder: (_, AsyncSnapshot<List<Post>> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (_, index) {
//dynamic post = snapshot.data[index];
return (Container(
margin: EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0),
child: new Card(
elevation: 10.0,
child: new Container(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Text(snapshot.data[index].name, style: TextStyle(fontSize: 18.0),),
new Text(snapshot.data[index].msg, style: TextStyle(fontSize: 18.0),),
new Text(snapshot.data[index].day, style: TextStyle(fontSize: 18.0),),
new Text(snapshot.data[index].date, style: TextStyle(fontSize: 18.0),),
],
),
),
),
));
},
);
},
);
}
#override
void initState() {
super.initState();
fetchPost();
}
}
class Post {
String name;
String msg;
String day;
String date;
Post({this.name, this.msg, this.day, this.date});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
name: json['name'],
msg: json['msg'],
day: json['day'],
date:json['date']
);
}
}
How to fix this issue?.
Thanks in advance.
I've looked at your link and tried running the code and I think the issue is in the data returned from your link.
[{"name":"م.م علي ستار باراني","msg":"امتحان مادة قواعد البيانات اول جابترين ","day":"السبت","date":"2019-06-20"}][{"name":"م. امجد عباس التميمي","msg":"امتحان مادة هندسة البرامجيات اول فصلين","day":"الاحد","date":"2019-06-21"},{"name":"م.م علي ستار باراني","msg":"امتحان مادة قواعد البيانات اول جابترين ","day":"السبت","date":"2019-06-20"}]
Right after the first object, you have a closing square bracket and no comma separating it from the opening square bracket beside it. Calling json.decode() on the link body throws the following error
FormatException (FormatException: Unexpected character (at character 115)
...,"day":"السبت","date":"2019-06-20"}][{"name":"م. امجد عباس التميمي","msg...
^
)
After fixing that, it runs fine for me. I tested by taking the body of the link manually and removing the offending characters, leaving me with the json below.
[{"name":"م.م علي ستار باراني","msg":"امتحان مادة قواعد البيانات اول جابترين ","day":"السبت","date":"2019-06-20"},{"name":"م. امجد عباس التميمي","msg":"امتحان مادة هندسة البرامجيات اول فصلين","day":"الاحد","date":"2019-06-21"},{"name":"م.م علي ستار باراني","msg":"امتحان مادة قواعد البيانات اول جابترين ","day":"السبت","date":"2019-06-20"}]
Running the app now displays the following:
make sure to always check for nulls in itemCount like this
ListView.builder(
itemCount: snapshot.data.length == null ? 0 :snapshot.data.length,
itemBuilder: (_, index){}
),
With this if your list is null, the itemCount will return a 0.
Just do this to the list List<Post> _postList = [] that happens its that everything it a object in Dart so when you do this List<Post> _postList = new List<Post>(); your variable _postList is equal to null because has been declared but not initialize so by default it null and you will not be able to use any property for the list until it initialize.
in resume just initialize your list like this: an empty list
List<Post> _postList = [];
So you don't have that issue.
Related
I've spent around an hour looking for this solution somewhere online. I'm new to flutter & dart languages but I'm very comfortable with C# and .net. Even tho dart/flutter use C# syntax a lot of the language feels much different than I thought it would.
I have a restful API in .net which returns a json object of String : String and String : [Array of Strings]. I have an object class within flutter where I can deserialize the response. I already done this with a normal response of just List and String without a problem but now I ran into massive problem. I don't have a clue how I can deserialise a Json that looks like this.
As requested
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
centerTitle: true,
backgroundColor: Colors.blueGrey,
foregroundColor: Colors.white,
),
drawer: const NavigationDrawer(),
body: Column(
children: [
Center(
child: Text(templateName),
),
Center(
child: FutureBuilder<TemplateContentAndArgumentsObject>(
future: templateContent,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Text(snapshot.data?.TemplateContent ?? "null");
} else {
return CircularProgressIndicator();
}
},
),
),
],
),
);
Api Call Code
Future<TemplateContentAndArgumentsObject> getTemplateContent(
String customerId, String templateName) async {
var url = Uri.parse(
'https://localhost:7167/api/v1/Templates/$customerId/$templateName');
var response = await http.get(url, headers: {
"Accept": "application/json",
"Access-Control-Allow-Origin": "*"
});
try {
print(response.body);
var sm = json.decode(response.body);
print(sm);
} catch (ex) {
print(ex);
}
if (response.statusCode == 200) {
TemplateContentAndArgumentsObject obj =
TemplateContentAndArgumentsObject.fromJson(json.decode(response.body));
print(obj.TemplateContent);
print(obj.TemplateArguments);
return obj;
} else {
print('Request failed with status: ${response.statusCode}');
}
return TemplateContentAndArgumentsObject(
TemplateContent: "", TemplateArguments: new List<String>.empty());
}
Class Object
import 'package:flutter/cupertino.dart';
class TemplateContentAndArgumentsObject {
String TemplateContent;
List<String> TemplateArguments;
TemplateContentAndArgumentsObject({
required this.TemplateContent,
required this.TemplateArguments,
});
factory TemplateContentAndArgumentsObject.fromJson(
Map<String, dynamic> json,
) =>
TemplateContentAndArgumentsObject(
TemplateContent: json["TemplateContent"] as String,
TemplateArguments: (json["TemplateArguments"] as List<String>),
);
}
Image of Json
Below is Sample Code for your problem. Please be aware that the code is just created based on your example where your list just contains String objects. In case your list contains more advanced objects, we should model them individually and put into a list. But for the strings you can do something like this:
class TemplateContentAndArgumentsObject {
String myStringContent;
List<String> myArrayContent;
TemplateContentAndArgumentsObject({
required this.myStringContent,
required this.myArrayContent,
});
factory TemplateContentAndArgumentsObject.fromJson(
Map<String, dynamic> json,
) =>
TemplateContentAndArgumentsObject(
myStringContent: json["myStringContent"] as String,
myArrayContent:
(json["myArrayContent"] as List<dynamic>).cast<String>(),
);
Map<String, Object> toJson() => {
"stringContnet": myStringContent,
"arrayCOntnet": myArrayContent,
};
}
I have changed the fromJson constructor into a factory constructor that just calls the class constructor. By doing so it removes the need for the class variables to be declared late.
Hey you can modify your build method, you need to check condition snapshot.hasData, for more detail see FutureBuilder
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
centerTitle: true,
backgroundColor: Colors.blueGrey,
foregroundColor: Colors.white,
),
drawer: const NavigationDrawer(),
body: Column(
children: [
Center(
child: Text(templateName),
),
Center(
child: FutureBuilder<TemplateContentAndArgumentsObject>(
future: templateContent,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data?.TemplateContent ?? "");
}else if (snapshot.hasError){
/// return error widget
return Container();
} else {
return CircularProgressIndicator();
}
},
),
),
],
),
);
//map to String
Map<String, dynamic> mapData = {
"username":name,
"email":email,
"phoneNumber":mobileNo,
"password":password ,
"refCode": inviteCode,
"countryCode":countryCode,
"country": "india"
};
json.encode(mapData);
// map to list
List values = List();
mapData.forEach((v) => values.add(v));
print(values);
I'm trying out the StreamBuilder so I call the API and the return values of the snapshot are always null. When I print the print(snapshot.error.toString()); it returns null. I've tried parsing the data differently but failed to do so. Here is the complete code:
var posts = <Post>[];
var controller = StreamController<List<Post>>();
#override
void initState() {
super.initState();
fetchPosts();
}
fetchPosts() async {
final resp =
await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
final data = json.decode(resp.body);
posts = data.map<Post>((e) => Post()).toList();
print(posts.isEmpty); // returns false
pirnt(data); // returns the entire data
controller.add(posts);
}
bool isSwitched = false;
void toggleSwitch(bool value) {
if (isSwitched == false) {
controller.add(posts..sort((k1, k2) => k1.id.compareTo(k2.id)));
print('Switch Button is ON');
} else {
controller.add(posts..sort((k1, k2) => k2.id.compareTo(k1.id)));
print('Switch Button is OFF');
}
}
#override
Widget build(BuildContext context) {
return Column(
children: [
Row(
children: [
Expanded(
child: TextButton(
child: Text('sort ascending'),
onPressed: () {
toggleSwitch(isSwitched = !isSwitched);
}),
),
],
),
Expanded(
child: StreamBuilder<List<Post>>(
initialData: posts,
stream: controller.stream,
builder: (ctx, snapshot) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
print(snapshot.error.toString);
Post post = snapshot.data[index];
return ListTile(
title: Text('${posts[index].id}'), // returns null
subtitle: Text('${post.id}'), // returns null
trailing: Text('${snapshot.data[index].id}'), // returns null
);
},
);
},
),
),
],
);
}
The Post model:
import 'package:flutter/foundation.dart';
import 'dart:core';
class Post extends ChangeNotifier {
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'],
);
}
}
Am I parsing the data wrong in the API call? Or is it something else? Thanks in advance for the help.
So my new teacher/friend #pskink that makes me learn and makes me use my brain these days, again helped me realize the mistake. Always make sure you are parsing the JSON data as it should. In my case, I forgot the fromJson(e) in the fetchPosts() method.
So the answer to this problem is:
posts = data.map<Post>((e) => Post.fromJson(e)).toList();
I'm trying to add my data to a Favorited list but I have no idea how to do that I just saved it in Favorited list but when restart the app nothing saved any idea how to save in shared preferences or some thing like it
code for loading json as follows
List mydata = List();
final _savedata = Set<Map>();
Future<void> getjsondata() async {
final String response = await rootBundle.loadString('assets/data.json');
final data = await json.decode(response);
setState(() {
mydata = data["InfoPlate"];
});
}
and this one for add data to favorited list
void _pushSaved() {
Navigator.of(context).push(
new MaterialPageRoute<void>(
builder: (BuildContext context) {
final Iterable<ListTile> tiles = _savedata.map(
(Myinfo) {
return new ListTile(
title: Text(Myinfo['type']),
);
},
);
final List<Widget> divided = ListTile.divideTiles(
context: context,
tiles: tiles,
).toList();
return new Scaffold(
appBar: new AppBar(
title: const Text('Favorited info Plate '),
),
body: new ListView(children: divided),
);
},
),
);
}
and this is the rest of code for the adding button in card
Widget _buildDataList() {
return ListView.builder(
itemCount: mydata.length,
padding: const EdgeInsets.all(8.0),
itemBuilder: (context, int index) {
return _buildRowInfo(mydata[index]);
});
}
Widget _buildRowInfo(Map myinfo) {
final bool favourited = _savedata.contains(myinfo);
void _favorscreen() {
setState(() {
if (favourited) {
_savedata.remove(myinfo);
} else {
_savedata.add(myinfo);
}
});
}
return Directionality(
textDirection: TextDirection.rtl,
child: Card(
child: ListTile(
visualDensity: VisualDensity.comfortable,
title: Text(myinfo['type']),
trailing: new IconButton(
icon: Icon(favourited ? Icons.favorite : Icons.favorite_border),
color: favourited ? Colors.red : null,
onPressed: _favorscreen,
),
),
),
);
}
}
It is possible to store data locally using shared_preferences.
All you need is an instance of SharedPreferences.
class ExampleWidget extends StatefulWidget {
#override
_ExampleWidgetState createState() => _ExampleWidgetState();
}
class _ExampleWidgetState extends State<ExampleWidget> {
SharedPreferences sharedPreferences;
#override
void initState() {
super.initState();
Future.delayed(Duration.zero, () async {
sharedPreferences = await SharedPreferences.getInstance();
});
}
Then, to read or write data, sharedPreferences is a key-value database and exposes setters and getters. It does not allow to store Set, so you will need to encode and decode data payload depending on the operation you perform.
Future<bool> _writeData(Set<Map> setOfMaps) {
return sharedPreferences.setString(
'your_key',
jsonEncode(setOfMaps.toList()),
);
}
Set<Map> _readData() {
final encodedData = sharedPreferences.getString('your_key');
return jsonDecode(encodedData).toSet();
}
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);
I am building an APP using pagewise package and would like to get the totalCount var from an external JSON request.
I have a function that returns an INT value that will be the totalCount but when added to the totalCount parameter it returns an error:
type 'Future<int>' is not a subtype of type 'int'
How can I solve this matter?
UPDATE:
return PagewiseGridView(
pageSize: 6,
totalCount: getTotals(),
crossAxisCount: 2,
mainAxisSpacing: 8.0,
crossAxisSpacing: 8.0,
childAspectRatio: 0.555,
padding: EdgeInsets.all(15.0),
itemBuilder: this._itemBuilder,
pageFuture: BackendService.getPage,
);
this is the class that creates the grid.
The problem is that you can't pass a future to a variable that expects an int.
You need to await for the future to complete and while you are awaiting you could, for instance, display a centered circular indicator.
This is something that you could use in your State class:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
State createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _totalCounter = -1;
#override
void initState() {
super.initState();
getTotalCounter();
}
void getTotalCounter() async {
_totalCounter = await getTotals();
setState(() {});
}
// Simulate your future
Future<int> getTotals() {
return Future.delayed(Duration(seconds: 3), () => 100);
}
#override
Widget build(BuildContext context) {
return _totalCounter == -1
? Center(child: CircularProgressIndicator())
: PagewiseGridView(
pageSize: 6,
totalCount: _totalCounter,
crossAxisCount: 2,
mainAxisSpacing: 8.0,
crossAxisSpacing: 8.0,
childAspectRatio: 0.555,
padding: EdgeInsets.all(15.0),
itemBuilder: this._itemBuilder,
pageFuture: BackendService.getPage,
);
}
}
From the dart documentation:
A future is a Future object, which represents an asynchronous operation that produces a result of type T.
In your case it is something you need access the info after it was retrieved async.
// Performing a request
// ... some widget
// ... child/Center is here just to exemplify how to use this Future inside a widget
// child: Center(child:
FutureBuilder<CustomList>(
future: fetchPost(),
builder: (context, snapshot) {
if (snapshot.hasData) {
// USE HERE THE DATA:
// snapshot.data.allCustoms
// snapshot.data.allCustoms.length
// for example you can create a ListView here
enter code here
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
})
// Making a request example (called above)
Future<CustomList> fetchPost() async {
final response = await http
.get('https://some_api_example');
if (response.statusCode == 200) {
// was successful, parse
return CustomList.fromJson(json.decode(response.body));
} else {
// not successful, throw.
throw Exception('Failed to load post');
}
}
// Some custom object we need to parse
class Custom {
final String id;
final String info;
Custom({this.id, this.info});
factory Custom.fromJson(Map<String, dynamic> json) {
return Custom(
id: json['id'].replaceAll(" ", ""),
info: json['info'].replaceAll(" ", "")
);
}
}
// A list of custom objects we parse from the reqeust
class CustomList {
final List<Custom> allCustoms;
CustomsList({
this.allCustoms,
});
factory CustomList.fromJson(List<dynamic> parsedJson) {
allCustoms = new List<Custom>();
allCustoms = parsedJson.map((i) => Custom.fromJson(i)).toList();
return new CustomList(
allCustoms: allCustoms,
);
}
}
Could you please try the following code and let me know what error are you getting.
return FutureBuilder<CustomList>(
future: fetchPost(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return PagewiseGridView(
pageSize: 6,
totalCount: snapshot.data,
crossAxisCount: 2,
mainAxisSpacing: 8.0,
crossAxisSpacing: 8.0,
childAspectRatio: 0.555,
padding: EdgeInsets.all(15.0),
itemBuilder: this._itemBuilder,
pageFuture: BackendService.getPage,
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
})