I'm new to flutter so bear with me that. I am currently making an application that uses HERE Maps API to get location data, but I'm getting "An error has occurred!", which comes when snapshot has no data.
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
// To parse this JSON data, do
//
// final hereRestLocation = hereRestLocationFromJson(jsonString);
HereRestLocation hereRestLocationFromJson(String str) => HereRestLocation.fromJson(json.decode(str));
String hereRestLocationToJson(HereRestLocation data) => json.encode(data.toJson());
class HereRestLocation {
List<Item> items;
HereRestLocation({
required this.items,
});
factory HereRestLocation.fromJson(Map<String, dynamic> json) => HereRestLocation(
items: List<Item>.from(json["items"].map((x) => Item.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"items": List<dynamic>.from(items.map((x) => x.toJson())),
};
}
//from here
// Future<http.Response> fetchHereRestLocation(http.Client client) async {
// return client.get(Uri.parse('https://discover.search.hereapi.com/v1/discover?at=40.7307999,-73.9973085&limit=2&q=Liberty&apiKey=**My API key here**'));
// }
List <HereRestLocation> parseHereRestLocation(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<HereRestLocation>((json) => HereRestLocation.fromJson(json)).toList();
}
Future <List<HereRestLocation>> fetchHereRestLocation(http.Client client) async {
final response = await client.get(Uri.parse('https://discover.search.hereapi.com/v1/discover?at=40.7307999,-73.9973085&limit=2&q=Liberty&apiKey=**My API key here**'));
// return parseHereRestLocation(response.body);
// Use the compute function to run parsePhotos in a separate isolate.
return compute(parseHereRestLocation,response.body);
}
//to here
class Item {
String title;
String id;
String language;
String resultType;
String localityType;
ItemAddress address;
Highlights highlights;
Item({
required this.title,
required this.id,
required this.language,
required this.resultType,
required this.localityType,
required this.address,
required this.highlights,
});
factory Item.fromJson(Map<String, dynamic> json) => Item(
title: json["title"],
id: json["id"],
language: json["language"],
resultType: json["resultType"],
localityType: json["localityType"],
address: ItemAddress.fromJson(json["address"]),
highlights: Highlights.fromJson(json["highlights"]),
);
Map<String, dynamic> toJson() => {
"title": title,
"id": id,
"language": language,
"resultType": resultType,
"localityType": localityType,
"address": address.toJson(),
"highlights": highlights.toJson(),
};
}
class ItemAddress {
String label;
String countryCode;
String countryName;
String state;
String county;
String city;
ItemAddress({
required this.label,
required this.countryCode,
required this.countryName,
required this.state,
required this.county,
required this.city,
});
factory ItemAddress.fromJson(Map<String, dynamic> json) => ItemAddress(
label: json["label"],
countryCode: json["countryCode"],
countryName: json["countryName"],
state: json["state"],
county: json["county"],
city: json["city"],
);
Map<String, dynamic> toJson() => {
"label": label,
"countryCode": countryCode,
"countryName": countryName,
"state": state,
"county": county,
"city": city,
};
}
class Highlights {
List<Title> title;
HighlightsAddress address;
Highlights({
required this.title,
required this.address,
});
factory Highlights.fromJson(Map<String, dynamic> json) => Highlights(
title: List<Title>.from(json["title"].map((x) => Title.fromJson(x))),
address: HighlightsAddress.fromJson(json["address"]),
);
Map<String, dynamic> toJson() => {
"title": List<dynamic>.from(title.map((x) => x.toJson())),
"address": address.toJson(),
};
}
class HighlightsAddress {
List<Title> label;
List<Title> city;
HighlightsAddress({
required this.label,
required this.city,
});
factory HighlightsAddress.fromJson(Map<String, dynamic> json) => HighlightsAddress(
label: List<Title>.from(json["label"].map((x) => Title.fromJson(x))),
city: List<Title>.from(json["city"].map((x) => Title.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"label": List<dynamic>.from(label.map((x) => x.toJson())),
"city": List<dynamic>.from(city.map((x) => x.toJson())),
};
}
class Title {
int start;
int end;
Title({
required this.start,
required this.end,
});
factory Title.fromJson(Map<String, dynamic> json) => Title(
start: json["start"],
end: json["end"],
);
Map<String, dynamic> toJson() => {
"start": start,
"end": end,
};
}
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
const appTitle = 'Isolate Demo';
return const MaterialApp(
title: appTitle,
home: MyHomePage(title: appTitle),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: FutureBuilder<List<HereRestLocation>>(
future: fetchHereRestLocation(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Center(
child: Text('An error has occurred!'),
);
} else if (snapshot.hasData) {
return MapList(items: snapshot.data!);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}
}
class MapList extends StatelessWidget {
const MapList({super.key, required this.items});
final List<HereRestLocation> items;
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: items.length,
itemBuilder: (context, index) {
return Text(items[index].title);
},
);
}
}
If needed, JSON response for the above API call from browser is like:
{"items":[{"title":"Liberty","id":"here:pds:place:840dr5r0-54fff946ce707baf510ad4123b26813d","language":"en","ontologyId":"here:cm:ontology:liberty","resultType":"place","address":{"label":"Liberty, 2509 Victory Blvd, Staten Island, NY 10314-6634, United States","countryCode":"USA","countryName":"United States","stateCode":"NY","state":"New York","county":"Richmond","city":"Staten Island","district":"Graniteville","street":"Victory Blvd","postalCode":"10314-6634","houseNumber":"2509"},"position":{"lat":40.61038,"lng":-74.14678},"access":[{"lat":40.61022,"lng":-74.14673}],"distance":18390,"categories":[{"id":"700-7600-0116","name":"Gas Station","primary":true}],"chains":[{"id":"4792","name":"Liberty"}],"references":[{"supplier":{"id":"core"},"id":"1130469039"},{"supplier":{"id":"yelp"},"id":"KbW5ssi1UCdbVd_Oodxe7w"}],"contacts":[{"phone":[{"value":"+17189826797"},{"value":"+17189829369"}],"www":[{"value":"http://www.liberty.edu"}]}],"openingHours":[{"text":["Mon-Sun: 00:00 - 24:00"],"isOpen":true,"structured":[{"start":"T000000","duration":"PT24H00M","recurrence":"FREQ:DAILY;BYDAY:MO,TU,WE,TH,FR,SA,SU"}]}],"payment":{"methods":[{"id":"mastercard","accepted":true}]}},{"title":"Liberty","id":"here:pds:place:840dr4y0-57e980bf79d04227a9cd14a94e7c9384","language":"en","ontologyId":"here:cm:ontology:liberty","resultType":"place","address":{"label":"Liberty, 118 US Highway 202, Ringoes, NJ 08551-1920, United States","countryCode":"USA","countryName":"United States","stateCode":"NJ","state":"New Jersey","county":"Hunterdon","city":"Ringoes","street":"US Highway 202","postalCode":"08551-1920","houseNumber":"118"},"position":{"lat":40.46667,"lng":-74.8599},"access":[{"lat":40.46666,"lng":-74.85998}],"distance":78526,"categories":[{"id":"700-7600-0116","name":"Gas Station","primary":true},{"id":"600-6000-0061","name":"Convenience Store"}],"chains":[{"id":"4792","name":"Liberty"}],"contacts":[{"phone":[{"value":"+19088066633"}],"www":[{"value":"http://www.liberty.edu","categories":[{"id":"700-7600-0116"}]}]}],"payment":{"methods":[{"id":"mastercard","accepted":true}]}}]}
I tried using https://app.quicktype.io/ to get classes as well, but here I am.
Future<HereRestLocation> fetch() async {
final response = await http.get(Uri.parse(URL));
final jsonResponse = jsonDecode(response.body);
if (response.statusCode == 200) {
HereRestLocation hereRestLocation = HereRestLocation.fromJson(jsonResponse);
for (Item item in hereRestLocation.items) {
debugPrint(item.id.toString());
}
return hereRestLocation;
} else {
throw Exception("Something Went Wrong");
}
}