Among other features Getx provides easy and complete solutions for http Get and Post request.
We created a class named ApiClient. You can name it anything.
Since we are going to pass base url to our class, we extend GetConnect. And this ApiClient class is a controller we will implement GetxService.
So we declared a variable name appBaseUrl.
Since we wanna able to deal with token, we delcared token variable and we wanna save this token to SharedPreferences so, we delcared sharedPreferences variable as well.
In this case we also wanna do authorization using token, we declared another variable name _mainHeaders.
So now our class looks like below
class ApiClient extends GetConnect implements GetxService{
late String token;
final String appBaseUrl;
final SharedPreferences sharedPreferences;
late Map<String, String> _mainHeaders;
}
Since appBaseUrl and sharedPreferences are final, we need to send the values for them when we call the contrusctor.
Other late variables should be initialized in the contructor body.
ApiClient Constructor
Based on the above fields we have declared, we will initialize out constructor.
ApiClient({required this.sharedPreferences, required this.appBaseUrl}) {
baseUrl = appBaseUrl;
// timeout = Duration(seconds: 5);
token = sharedPreferences.getString(AppConstants.TOKEN)??"";
_mainHeaders = {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer $token',
};
}
Once we call the call constructor, we will send sharedPrefrence and appBaseUrl. See how token and _mainHeaders are initialized in the contructor body.
Getx Http Requests
Getx provides get() and post() methods just like Http package http.get and http.post. If you used http.get() and http.post(), you will find that they are very similar with get() and post() methods of Getx.
get() method
Let's take a look at the get method. There parameters that get() method takes, but not all of them are required.
await get(
uri,
contentType: contentType,
query: query,
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer $token', //carrier
},
decoder: decoder,
);
Only the uri is required. Others are optional named parameters. If you set the base url in the ApiClient constructor, then you send then end point to uri.
get() method returns a response, we need to save this reponse in a Response type variable. This Response object is Getx object from get_connect package.
We will wrap the get() method inside our custom method. We call it getData()
Future<Response> getData(String uri,
{Map<String, dynamic>? query, String? contentType,
Map<String, String>? headers, Function(dynamic)? decoder,
}) async {
try {
Response response = await get(
uri,
contentType: contentType,
query: query,
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer $token', //carrier
},
decoder: decoder,
);
response = handleResponse(response);
return response;
} catch (e) {
return Response(statusCode: 1, statusText: e.toString());
}
}
The method get() returns a response and we saved it in Response response obect. This Response is Getx get_connect
post() method
Let's take a look at the post() method. There parameters that post() method takes, but not all of them are required.
await post(
uri, body,
// query: query,
// contentType: contentType,
headers: _mainHeaders,
);
Here most important parameters are uri and body. Others are optional.
Complete code
class ApiClient extends GetConnect implements GetxService{
late String token;
final String appBaseUrl;
final SharedPreferences sharedPreferences;
late Map<String, String> _mainHeaders;
ApiClient({required this.sharedPreferences, required this.appBaseUrl}) {
baseUrl = appBaseUrl;
// timeout = Duration(seconds: 5);
token = sharedPreferences.getString(AppConstants.TOKEN)??"";
_mainHeaders = {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer $token',
};
}
void updateHeader(String token) {
_mainHeaders = {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer $token',
};
}
Future<Response> getData(String uri,
{Map<String, dynamic>? query, String? contentType,
Map<String, String>? headers, Function(dynamic)? decoder,
}) async {
try {
Response response = await get(
uri,
contentType: contentType,
query: query,
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer $token', //carrier
},
decoder: decoder,
);
response = handleResponse(response);
return response;
} catch (e) {
return Response(statusCode: 1, statusText: e.toString());
}
}
Future<Response> postData(String uri, dynamic body,) async {
try {
Response response = await post(
uri, body,
// query: query,
// contentType: contentType,
headers: _mainHeaders,
);
response = handleResponse(response);
if(Foundation.kDebugMode) {
log('====> GetX Response: [${response.statusCode}] $uri\n${response.body}');
}
return response;
}catch (e) {
return Response(statusCode: 1, statusText: e.toString());
}
}
Response handleResponse(Response response) {
Response _response = response;
if(_response.hasError && _response.body != null && _response.body is !String) {
if(_response.body.toString().startsWith('{errors: [{code:')) {
_response = Response(statusCode: _response.statusCode, body: _response.body, statusText: "Error");
}else if(_response.body.toString().startsWith('{message')) {
_response = Response(statusCode: _response.statusCode,
body: _response.body,
statusText: _response.body['message']);
}
}else if(_response.hasError && _response.body == null) {
print("The status code is "+_response.statusCode.toString());
_response = Response(statusCode: 0, statusText: 'Connection to API server failed due to internet connection');
}
return _response;
}
}