How to get the json from API - flutter

What I want to do is get the json from API and make the buttons from the json content.
API response doesn't change, so I want to call this just one time.( not need to recall when reloading the widget)
So, my idea is simply call the API from initState
Future<List> getSmartTags() async {
var url = Uri.parse("http://localhost:8008/api/smarttags/");
var resp = await http.get(url);
return json.decode(resp.body);
}
and want to confirm json is correctly returned.
void initState() {
super.initState();
var temp = getSmartTags();
print(temp);
}
This error occurs.
[VERBOSE-2:ui_dart_state.cc(198)] Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'FutureOr<List<dynamic>>'
#0 _SmartTagState.getSmartTags (package:flutter_aic/main.dart:64:17)
I think this is the basic concept of Future though, I didn't get it.

I think you're getting back a Map<String, dynamic> whenever you decode your html body with json, and not a List.
Furthermore, your return value is not a Future because of the await. Whenever the request is done, the final value is stored in your variable resp.
So, theoretically, it should work like this:
Map<String, dynamic> getSmartTags() async {
var url = Uri.parse("http://localhost:8008/api/smarttags/");
var resp = await http.get(url);
return json.decode(resp.body);
It would return a Future<Map<String, dynamic>> instead, when you write it without the wait.
And to avoid more errors because of your async function and the print() outside, I would recommend you to print the JSON output inside your function, not in initState.

Related

I see this error when run my app type 'string' is not a subtype of type 'int' of 'index' flutter when I using http

when I want to get a value from a json form in flutter, i face this error it says
type 'String' is not a subtype of type 'int' of 'index'
and Im using http: ^0.13.4
and this is my code
void getData() async{
Response res=await get("https://something.com");
String dat=res.body;
var datta=jsonDecode(dat)['title'];
print(datta);
}
how can I fix this problem?
dont forget to write Uri.parse
void getData() async{
Response res=await get(Uri.parse("https://something.com"));
String dat=res.body;
var datta=jsonDecode(dat)['title'];
print(datta);
}
You should handle the request in this way, worked for me:
void getData() async {
String baseUrl = "something.com";
String endpoint = "/your/endpoint";
Uri url = Uri.https(baseUrl, endpoint, {});
http.Response response = await http.get(url);
// Error handling
// if (response.statusCode != "200") {
// sendError();
// }
String stringBody = response.body;
}
Then you convert the string into a JSON object using dart:convert library:
import "dart:convert";
// Json object
Map<String, dynamic> jsonVar = json.decode(stringBody) as Map<String, dynamic>;
That should be enough, but I suggest you to implement a model class to handle your response, and another model to handle the kind of object you are working with (e.g. Book, Post, Product, etc).

Flutter - Can I use one google map api key for iOS, android and place autocomplete?

Do we have to use different google map API keys for each iOS, android, and place autocomplete?
currently, I am using one API key for all like this
and something is not working. the map suggests me the name of the locations when I type in the search text field, but I get the error when I tap on the name of the location. the error says
Unhandled Exception: type 'Null' is not a subtype of type 'Map<String, dynamic>' in typecast
I think I am doing something wrong with the API keys.
Do we have to use different keys for each platform?
here is my http request
Future<String> getPlaceId(String input) async {
final String url =
'https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=$input&inputtype=textquery&key=$autocompletekey';
final response = await http.get(Uri.parse(url));
var json = convert.jsonDecode(response.body);
var placeId = json['candidates'][0]['place_id'] as String;
print(placeId);
return placeId;
}
Future<Map<String, dynamic>> getPlace(String input) async {
final placeId = await getPlaceId(input);
final String url =
'https://maps.googleapis.com/maps/api/place/findplacefromtext/json?place_id=$placeId&key=$autocompletekey';
final response = await http.get(Uri.parse(url));
var json = convert.jsonDecode(response.body);
var results = json['result'] as Map<String, dynamic>; // this line of code produces error
print(results);
return results;
}

Cannot access decoded json body flutter

I'm fetching data in flutter and created a helper class as seen below
import 'dart:convert';
import 'package:http/http.dart' as http;
class HttpClient {
final Map<String, String> _headers = {};
void setHeader(String key, String value) {
if (!_headers.containsKey(key)) {
_headers[key] = value;
}
}
Future<http.Response> get(String url) async {
try {
var uri = Uri.parse(url);
var response = await http.get(uri, headers: _headers);
if (response.statusCode == 200) {
dynamic result = jsonDecode(response.body);
return result;
} else {
throw Error();
}
} on Exception catch (_) {
rethrow;
}
}
}
HttpClient appClient = HttpClient();
I call the method from a class as shown below
abstract class AbstractTodoService {
dynamic getTodos() {}
}
class HttpTodoService implements AbstractTodoService {
#override
Future<Response> getTodos() async {
try {
var todos =
await appClient.get('https://jsonplaceholder.typicode.com/todos');
print(todos);
return todos;
} on Exception catch (error) {
print(error);
rethrow;
}
}
}
However, when I print todos or any string in the HttpTodoService after the await call to the HttpClient I do not see anything. However, when I print the result inside the HttpClient I see the response but does not return. When I return a normal string or map everything works normally but when I attempt to use the jsonDecoded response nothing returns.
Your jsonDecode(response.body); returns a List<dynamic> type, but your function return type is Future<http.Response>. This is why you are not getting data.
You can check runtime datatype of a variable by
print(result.runtimeType); // variable_name.runtimeType
Change function return types to Future<List<dynamic>> of get(String url) and getTodos() functions.
It might be because your function returns a future of http.Response which is actually the type of the response after you use http.get. After you use jsonDecode you should get a Map<String, dynamic> which represent the json.
From the documentation:
By looking at the dart:convert documentation, you’ll see that you can decode the JSON by calling the jsonDecode() function, with the JSON string as the method argument.
Map<String, dynamic> user = jsonDecode(jsonString);
print('Howdy, ${user['name']}!');
print('We sent the verification link to ${user['email']}.');
Unfortunately, jsonDecode() returns a Map<String, dynamic>, meaning that you do not know the types of the values until runtime. With this approach, you lose most of the statically typed language features: type safety, autocompletion and most importantly, compile-time exceptions. Your code will become instantly more error-prone.
For example, whenever you access the name or email fields, you could quickly introduce a typo. A typo that the compiler doesn’t know about since the JSON lives in a map structure.
After you use jsonDecode you should turn the map into the object you want to work with using factory fromJson method.
You can read more about is in the documentation https://flutter.dev/docs/development/data-and-backend/json

Flutter: return int variable from future function is stateless widget : Edited and changed

I have stateless widget contain future function to get a value (not a list) from database:
Future<int> getUserStatus() async {
var url =
"http:/xxxxxx/api/controller/users/status_user.php?username=$username";
var response = await http.get(url);
var data = jsonDecode(response.body);
var savedDayID = int.parse(data['d_id'].toString());
return savedDayID;
}
How can I put the value returned in a variable?
In general:
final myVariable = await getUserStatus();
Make sure to handle the exception that int.parse() could throw.
For building UI components, have a look at the FutureBuilder.
I'd reconsider the design of trying to do url fetching inside the build method. The reason being that the build method should be possible to run many times at the will of the framework.

JSON result not showing in flutter

This code seemed to work a month ago but when I returned to coding this today it shows an error.
I have no problem with my back-end as I checked it.
The code below returns:
'Unhandled Exception: type 'List' is not a subtype of type 'Map'
Map data;
List userData;
Future getItems() async {
http.Response response = await http.get("http://172.16.46.130/olstore_serv/get_items");
data = json.decode(response.body);
setState(() {
userData = data["item"];
});
}