Flutter'sTry Catch never works - flutter

I tried everything.. I always have some problem with async try catch blocks..
I read the guide that flutter has on it but nothing there works.. i am trying to make http requests, but whenever there is a problem like (connection refused) it breaks the code. i tried:
try {
switch (type) {
case RequestType.Get:
response = await _httpClient
.get(url, headers: headers)
.catchError(catchError);
break;
case RequestType.Put:
try {
response = await _httpClient
.put(url, body: body, headers: headers)
.catchError(catchError);
} catch (e) {
catchError();
}
break;
case RequestType.Post:
response = await _httpClient
.post(url, body: body, headers: headers)
.catchError(catchError);
break;
default:
return null;
break;
}
} catch (e) {
catchError();
}
I tried every combination there.. with async catchError only.. with try catch only.. with try catch above the switch, with try catch only on the http request.. NOTHING works.. How can this be done????

Keep one try...catch for all, keep it simple:
Future doRequest(type, url, headers) async {
try {
switch (type) {
case RequestType.Get: return await _httpClient.get(url, headers: headers);
case RequestType.Put: return await _httpClient.put(url, body: body, headers: headers);
case RequestType.Post: return await _httpClient.post(url, body: body, headers: headers);
}
throw('Method not supported');
} catch (e) {
// print exception to console
// or comment the line, if You don't care about error
print(e.error);
return null;
}
}
or avoid using try...catch in this logic and handle issue on higher level.
Future doRequest(type, url, headers) {
switch (type) {
case RequestType.Get: return _httpClient.get(url, headers: headers);
case RequestType.Put: return _httpClient.put(url, body: body, headers: headers);
case RequestType.Post: return _httpClient.post(url, body: body, headers: headers);
}
throw('Method not supported');
}
try {
final response = await doRequest(RequestType.Get, "some/url/here", {});
/* do something with response */
}
catch (error) {
//handle error here
}

Related

why i got on error on flutter dio implementation?

can someone help me to check why my code is error ?
i already make user freeze, network freeze. as we can see i try to use all dio package. i got more code on bellow. in here i give u image to show what error. i want to try to make flutter dio easier so i dont need to write network response multiple times.
import 'package:dio/dio.dart';
import 'package:latihan_dio/dio_interceptor.dart';
import 'package:latihan_dio/src/features/home/domain/network_response.dart';
import '../../../../dio_client.dart';
import '/src/features/home/domain/user.dart';
enum RequestType { GET, POST, PUT, PATCH, DELETE }
class DioClient {
final dio = createDio();
DioClient._internal();
static final _singleton = DioClient._internal();
factory DioClient() => _singleton;
static Dio createDio() {
var dio = Dio(BaseOptions(
baseUrl: "https://reqres.in/api/users?page=2",
receiveTimeout: 20000, // 20 seconds
connectTimeout: 20000,
sendTimeout: 20000,
));
// dio.interceptors.addAll({
// AuthInterceptor(dio),
// });
dio.interceptors.addAll({
Logging(dio),
});
return dio;
}
Future<NetworkResponse?> apiCall({
required String url,
required RequestType requestType,
Map<String, dynamic>? queryParameters,
Map<String, dynamic>? body,
Map<String, String>? header,
RequestOptions? requestOptions,
}) async {
late Response result;
// try {
switch (requestType) {
case RequestType.GET:
{
Options options = Options(headers: header);
result = await dio.get(url,
queryParameters: queryParameters, options: options);
break;
}
case RequestType.POST:
{
Options options = Options(headers: header);
result = await dio.post(url, data: body, options: options);
break;
}
case RequestType.DELETE:
{
Options options = Options(headers: header);
result =
await dio.delete(url, data: queryParameters, options: options);
break;
}
case RequestType.PUT:
{
Options options = Options(headers: header);
result = await dio.put(url, data: body, options: options);
break;
}
case RequestType.PATCH:
{
Options options = Options(headers: header);
result = await dio.patch(url, data: body, options: options);
break;
}
}
if(result != null) {
return NetworkResponse.success(result.data);
} else {
return const NetworkResponse.error("Data is null");
}
} on DioError catch (error) {
return NetworkResponse.error(error.message);
} catch (error) {
return NetworkResponse.error(error.toString());
}
}
but I don't think it has anything to do with the error above
I think because you made try as a comment.
You have written // try {.
Remove //

Flutter http post request gives status code 401

I am using API to verify phone number provided by user.... on postman api give perfect response and give OTP code in response but in flutter status code 401 is returned
here is my code
Future verifyPhone(String phoneNumber) async {
try {
String token = "528724967b62c6c9e546aeaee1b57e234991ad98";
var body = <String, String>{};
body['user_number'] = phoneNumber;
var url = Uri.parse(ApiKeys.phoneVerifyApiKey);
var response = await http.post(
url,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"authentication": "Bearer $token"
},
body: body,
);
if (response.statusCode == 200) {
print("Code sent");
} else {
print("Failed to send code");
print(response.statusCode);
}
} catch (err) {
print(err.toString());
}
notifyListeners();
}
instead of "code sent" i get "failed to send code" and status code 401
EDIT
You can send form request this way
Future verifyPhone(String phoneNumber) async {
try {
String token = "528724967b62c6c9e546aeaee1b57e234991ad98";
var body = <String, String>{};
body['user_number'] = phoneNumber;
var url = Uri.parse(ApiKeys.phoneVerifyApiKey);
var headers ={
"Content-Type": "application/x-www-form-urlencoded",
"authentication": "Bearer $token"
};
var request = http.MultipartRequest('POST', url)
..headers.addAll(headers)
..fields.addAll(body);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print("Code sent");
} else {
print("Failed to send code");
print(response.statusCode);
}
} catch (err) {
print(err.toString());
}
notifyListeners();
}
EDIT
To access :
var _data = jsonDecode(response);
var list = _data["data"];
print(list[0]['otp_code']);

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");
}
}

flutter error 403 in post request using dio

i have a problem with hate. I'm trying to login using dio, the login method works perfectly, but when I put invalid credentials dio gives me this error:
DioError
Error in execution
I created a boolean function that would return true or false if the statuscode was 200 it would return true and if not it would return false, but when logging in with the right credentials everything is ok, everything happens as it should, but when logging in with invalid credentials this error above causes it. I'm using shared preferences to store the tolken in the app, and the logic would be simple, if it was 200 I would log into the app, otherwise it would show me a snackbar I made in another file, this is my code:
loginFinal() async {
if (formKey.currentState!.validate()) {
bool loginIsOk = await loginConect();
if (loginIsOk) {
Get.offAllNamed("/home");
await Future.delayed(const Duration(seconds: 1));
message(MessageModel.info(
title: "Sucesso",
message: "Seja bem vindo(a) influenciador(a)",
));
} else {
loaderRx(false); //LOADER
message(MessageModel.error(
title: "Erro",
message: "Erro ao realizar login",
));
}
}
}
//LOGICA DE ENTRAR NO APP
Future<bool> loginConect() async {
final dio = Dio();
String baseUrl = "https://soller-api-staging.herokuapp.com";
loaderRx(true); //LOADER
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
final response = await dio.post(
baseUrl + "/auth",
data: jsonEncode(
{
"login": emailController.text,
"senha": passWordController.text,
},
),
options: Options(
headers: {'Content-Type': 'application/json; charset=UTF-8'},
method: "post",
),
);
if (response.statusCode == 200) {
await sharedPreferences.setString(
"token",
"string: ${response.data["string"]}",
);
print("Resposta: ${response.data["string"]}");
loaderRx(false);
return true;
} else {
print("RESPOSTA: ${response.data}");
return false;
}
}
}
Dio always throw an exception if the status code in the header is not 200,
you will need to catch the exception using try catch.
In the catch method, you can check if the type of the error is DioError and then handle that exception,
Here is a code snippet of a login process that I use in my code to handle this behavior.
Future<SignInApiResponse> signInUser(String _email,String _password) async {
try {
final dio = Dio(ApiConstants.headers());
final Response response = await dio.post(
ApiConstants.baseUrl + ApiConstants.signInUrl,
data: {"email": _email,
"password": _password,
},
);
if (response.statusCode == 200) {
return SignInApiResponse.fromJson(response.data);
} else {
return SignInApiResponse(message: response.toString());
}
} catch (e) {
if (e is DioError) {
if (e.response?.data == null) {
return SignInApiResponse(message: Messages.loginFailed);
}
return SignInApiResponse.fromJson(e.response?.data);
} else {
return SignInApiResponse(message: e.toString());
}
}
}
hopefully, this will help
if not you can always use http package that does not throw an exception in similer case

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