How to get part from JSON using 'response.stream.bytesToString()' instead of "(response.body) ['data']" - flutter

Edit 1:
I am new to Flutter, and coding altogether, so please answer in simple terms.
I can get a JSON string from this API: [https://reqres.in/api/users?page=1][1]. using jsonDecode(response.body)
And I can also get specific part within this JSON using
jsonDecode(response.body)['data'] // 'data' is a List[]
But Postman, generates this completely different code to get data from api.
Postman uses response.stream.bytesToString());
Now I want to keep using Postman's auto generated code, but tweek it such that I get only the List, 'data', from the API.
My full code is:
class ApiService {
Future<List<UserModel>> getData() async {
try{
Response response = await get( Uri.parse('https://reqres.in/api/users?page=2'));
List result = await jsonDecode(response.body)['data'];
if (response.statusCode == 200) {
print(response);
print('');
print(response.body);
print('');
print(result);
print('');
return result.map((e) => UserModel.fromJson(e)).toList();
}
else {
print(response.reasonPhrase);
throw Exception(response.reasonPhrase);
}
} catch(e){
print('Error AA gaya \n\n\n $e') ;
throw e;
}
}
}
------------
Postman generated code is:
==========================
var request = http.Request('GET', Uri.parse('https://reqres.in/api/users?page=2'));
a
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
}
else {
print(response.reasonPhrase);
}
[1]: https://reqres.in/api/users?page=1

your code is correct but the way you parse is wrong
Future<List<UserModel>> getData() async {
try{
Response response = await get( Uri.parse('https://reqres.in/api/users?page=2'));
if (response.statusCode == 200) {
var jdata = jsonDecode(response.body);
print(response);
print('');
print(response.body);
print('');
print(jdata);
print('');
return jdata['data'].map((e) => UserModel.fromJson(e)).toList();
}
else {
print(response.reasonPhrase);
throw Exception(response.reasonPhrase);
}
} catch(e){
print('Error AA gaya \n\n\n $e') ;
throw e;
}
}

Related

Flutter Future Returns Null from API

I don't seem to know whats wrong with this code . it returns nothing
Future<Product> fetchProducts() async {
final response =
await http.get(Uri.parse('http://10.0.2.2:8000/api/products'));
if (response.statusCode == 200) {
// print(response.body);
return Product.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to load products');
}
}

GET api in flutter failing with I/flutter ( 4017): {code: 404, message: HTTP 404 Not Found}

My requirement is need to make get rest api call in flutter.my code is as below
final url = "https://app2.sas.com/uh/device/1890/publicKey";
https://app2.sas.com/ is my base url followed by api end point
should i need to add any certificate for https://app2.sas.com/ to work?
void getPublickey() async {
print('getPublickey');
try {
final response = await http.get(Uri.parse(url));
final jsonData = jsonDecode(response.body);
if (response.statusCode == 200) {
print(jsonData.toString());
} else {}
} catch (err) {
print(err.toString());
}
}
when i hit above api i m getting below response, please let me know any mistake i m doing above?
I/flutter ( 4017): {code: 404, message: HTTP 404 Not Found}
Any help is appreciated
try
Future <void>
instead of void and remove http
Future getPublickey() async {
print('getPublickey');
try {
final response = await get(Uri.parse(url));
final jsonData = jsonDecode(response.body);
if (response.statusCode == 200) {
print(jsonData.toString());
} else {}
} catch (err) {
print(err.toString());
}
}
I don't think the problem is from Flutter. Trying out your URL https://app2.sas.com/uh/device/1890/publicKey returns a 404 too.
You should double-check the URL and make sure the endpoint is correct.
You should probably be returning the string public key:
Future getPublickey() async {
print('getPublickey');
try {
final response = await http.get(Uri.parse(url));
final jsonData = jsonDecode(response.body);
if (response.statusCode == 200) {
print(jsonData.toString());
return jsonData;
} else {
print(response.statusCode);
return null;
}
} catch (err) {
print(err.toString());
return null;
}
}

Common method for flutter api calls

Is there any example that I can refer to about Common class/method for flutter API calls(GET,POST,...) in flutter? I have handled all the API requests in a common method in react native, I'm not sure how to implement it in flutter.
you have to call getRequest using url parameter
Future<Response> getRequest(String url) async {
Response response;
try {
response = await _dio.get(url,
options: Options(headers: {
HttpHeaders.authorizationHeader:
'Bearer $accessToken'
}));
print('response $response');
} on DioError catch (e) {
print(e.message);
throw Exception(e.message);
}
return response;
}
here is the post method
Future<Response> posRequestImage(String url, data) async {
try {
response = await _dio.post(
url,
data: formData,
options: Options(headers: {
HttpHeaders.authorizationHeader:
'Bearer $accessToken'
}),
);
if (response.statusCode == 200) {
return response;
}
print('post response $response');
} on DioError catch (e) {
print(e.message);
throw Exception(e.response?.statusMessage);
}
return response;
}
You can create a class to handle it. For example, this is my class to handle all service for user model
import 'package:http/http.dart' as http;
class UserService {
var baseUrl = URL.devAddress;
Future<User> getUser() async {
final response = await http.get(
Uri.parse(baseUrl + "user/1")
);
if (response.statusCode == 200) {
final data = json.decode(response.body);
return data
} else {
throw Exception("Failed");
}
}
}
Future<void> getUser(String username) async {
Uri uri = Uri.parse('https://example.com');
try {
Map<String, dynamic> params = new HashMap();
params['username'] = username;
final response = await client.post(uri,
body: jsonEncode(params),
);
print("response ${response.body}");
} on FetchDataException {
throw FetchDataException("No Internet connection");
}
}

Trying to make a request with http in Flutter

I am trying to make a class in Flutter that can send requests to an API and then store the response inside the class, however every time I send a request I get some sort of infinite request that end up in timing out. Here is my code:
When the user press the button in the screen:
onPressed: () async {
print('Email: ${emailFieldController.text} and password: ${passwordFieldController.text}');
await Api.sendRequest('POST', '/session', {
"email": emailFieldController.text,
"password": passwordFieldController.text
});
if (Api.content.containsKey("error")) {
print("Error connectiong with API");
print("The error was:" + Api.content["error"].toString());
} else {
if (Api.content["status"] == 200) {
print("User find");
} else {
print("User not find");
}
}
})
The class that I built:
import 'dart:convert';
import 'package:http/http.dart';
class Api {
static final String baseURL = 'http://192.168.15.4/api/v1';
static Map content;
static Future<void> sendRequest(String method, String endpoint, [Map body, Map headers]) async {
Response response;
switch (method) {
case 'GET':
try {
response = await get('$baseURL' + endpoint);
Api.content = jsonDecode(response.body);
} catch (e) {
Api.content["error"] = e.toString();
}
break;
case 'POST':
try {
response =
await post('$baseURL' + endpoint, body: body, headers: headers);
Api.content = jsonDecode(response.body);
print('Passando depois POST');
} catch (e) {
Api.content["error"] = e.toString();
}
break;
case 'PUT':
try {
response =
await put('$baseURL' + endpoint, body: body, headers: headers);
Api.content = jsonDecode(response.body);
} catch (e) {
Api.content["error"] = e.toString();
}
break;
case 'DELETE':
try {
response = await delete('$baseURL' + endpoint, headers: headers);
Api.content = jsonDecode(response.body);
} catch (e) {
Api.content["error"] = e.toString();
}
break;
}
}
}
I also tried to alter the return type of the method, but got the same result.
So I discovered what was wrong, baseURL attribute was missing the port, so the request never found it's target. So in the and the baseURL value was: http://192.168.15.4:3333/api/v1

How do I return error from a Future in dart?

In my flutter app, I have a future that handles http requests and returns the decoded data. But I want to be able to send an error if the status code != 200 that can be gotten with the .catchError() handler.
Heres the future:
Future<List> getEvents(String customerID) async {
var response = await http.get(
Uri.encodeFull(...)
);
if (response.statusCode == 200){
return jsonDecode(response.body);
}else{
// I want to return error here
}
}
and when I call this function, I want to be able to get the error like:
getEvents(customerID)
.then(
...
).catchError(
(error) => print(error)
);
Throwing an error/exception:
You can use either return or throw to throw an error or an exception.
Using return:
Future<void> foo() async {
if (someCondition) {
return Future.error('FooError');
}
}
Using throw:
Future<void> bar() async {
if (someCondition) {
throw Exception('BarException');
}
}
Catching the error/exception:
You can use either catchError or try-catch block to catch the error or the exception.
Using catchError:
foo().catchError(print);
Using try-catch:
try {
await bar();
} catch (e) {
print(e);
}
You can use throw :
Future<List> getEvents(String customerID) async {
var response = await http.get(
Uri.encodeFull(...)
);
if (response.statusCode == 200){
return jsonDecode(response.body);
}else{
// I want to return error here
throw("some arbitrary error"); // error thrown
}
}
Another way to solve this is by using the dartz package.
An example of how to use it would look something similar like this
import 'package:dartz/dartz.dart';
abstract class Failure {}
class ServerFailure extends Failure {}
class ResultFailure extends Failure {
final int statusCode;
const ResultFailure({required this.statusCode});
}
FutureOr<Either<Failure, List>> getEvents(String customerID) async {
try {
final response = await http.get(
Uri.encodeFull(...)
);
if (response.statusCode == 200) {
return Right(jsonDecode(response.body));
} else {
return Left(ResultFailure(statusCode: response.statusCode));
}
}
catch (e) {
return Left(ServerFailure());
}
}
main() async {
final result = await getEvents('customerId');
result.fold(
(l) => print('Some failure occurred'),
(r) => print('Success')
);
}
You can return the error data like this if you want to read the error object:
response = await dio.post(endPoint, data: data).catchError((error) {
return error.response;
});
return response;
//POST
Future<String> post_firebase_async({String? path , required Product product}) async {
final Uri _url = path == null ? currentUrl: Uri.https(_baseUrl, '/$path');
print('Sending a POST request at $_url');
final response = await http.post(_url, body: jsonEncode(product.toJson()));
if(response.statusCode == 200){
final result = jsonDecode(response.body) as Map<String,dynamic>;
return result['name'];
}
else{
//throw HttpException(message: 'Failed with ${response.statusCode}');
return Future.error("This is the error", StackTrace.fromString("This is its trace"));
}
}
Here is how to call:
final result = await _firebase.post_firebase_async(product: dummyProduct).
catchError((err){
print('huhu $err');
});