Issue
I am trying to read a lot of data from a JSON file in flutter. The data retrieval results in jank so I decided to use compute
but then it didn’t return any results.
This is my code with compute
that does not return data:
Future<List<City>> getCityList (BuildContext context) async{
final response = await DefaultAssetBundle.of(context).loadString('Assets/citylist.json');
final decoded = await compute(json.decode, response);
return decoded.map<City>((json) => fromJson(json)).toList();
}
This is my code without compute that does returns data but results in jank :
Future<List<City>> getCityList (BuildContext context) async{
final response = await DefaultAssetBundle.of(context).loadString('Assets/citylist.json');
final decoded = json.decode(response);
return decoded.map<City>((json) => fromJson(json)).toList();
}
This is the code for my Futurebuilder:
FutureBuilder(
future: getCityList(context),
builder: (context, snapshot) {
if (snapshot.hasData){
return ListView.builder(
itemCount: snapshot.data?.length ?? 0,
itemBuilder: (BuildContext context, int index) {
return FlatButton(
onPressed: (){
},
child: Container(
child: Text(snapshot.data[index].name, style: TextStyle(fontSize: 20.0, color: Theme.of(context).accentColor),),
padding: const EdgeInsets.all(15.0),
),
);
}
);
}
return Center(child: CircularProgressIndicator(),);
})
Solution
You cannot pass object methods(or closures) – instead, you need to path top-level functions.
Should be await compute(jsonDecode, response)
Where jsonDecode is top-level function from json.dart
.(just use jsonDecode
func instead of json.decode
)
Also, I suggest creating a method like decodeCities where you can decode and map your JSON.
Here u can find a sample and more details
Invalid argument(s): Illegal argument in isolate message : (object is a closure – Function 'createDataList':.)
Updated:
For tests I use next JSON(12mb)
https://raw.githubusercontent.com/lutangar/cities.json/master/cities.json
final decoded = await compute(decode, response);
print(decoded.length);
List<City> decode(dynamic obj) {
final decoded = jsonDecode(obj);
return decoded.map<City>((json) => City.fromJson(json)).toList();
}
class City {
String country;
String name;
String lat;
String lng;
City({this.country, this.name, this.lat, this.lng});
City.fromJson(Map<String, dynamic> json) {
country = json['country'];
name = json['name'];
lat = json['lat'];
lng = json['lng'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['country'] = this.country;
data['name'] = this.name;
data['lat'] = this.lat;
data['lng'] = this.lng;
return data;
}
}
Answered By – Yauhen Sampir
Answer Checked By – Mary Flores (FlutterFixes Volunteer)