How can I add request header automatically using http package - flutter

Currently I'm sending header with every request like as follow which is very repetitive.
Is there any process so that all my request will have a request header automatically ?
Or how can I avoid code repetition for the following lines:
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
String token = sharedPreferences.getString('accessToken');
headers: {
'Contet-type': 'application/json',
'Authorization': 'Bearer $token',
}
My complete API Request code:
Future<http.Response> getAUser(userId) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
String token = sharedPreferences.getString('accessToken');
return await http.get(
'$baseUrl/user/$userId/',
headers: {
'Contet-type': 'application/json',
'Authorization': 'Bearer $token',
},
).timeout(Duration(seconds: 30));
}

Yes you can centralize the headers in a separate class!
class BaseService {
Map<String, String> baseHeaders;
Future initBaseService() async {
final preferences = await SharedPreferences.getInstance();
baseHeaders= {
"Accept": "application/json",
"Content-Type": "application/json; charset=utf-8",
"Authorization": "Bearer ${preferences.getString("TOKEN")}",
};
}
}
And then, you can inherit your class with the base class to have access to these methods.
class UserService extends BaseService {
Future<http.Response> getAUser(userId) async {
await initBaseService();
return await http
.get(
'$baseUrl/user/$userId/',
headers: baseHeaders,
)
.timeout(Duration(seconds: 30));
}
}

Related

Can't get auth token stored in flutter secure storage to headers

I am making flutter app using API and I have a problem. When I want to get auth token to make request, flutter says that "Expected a value of type 'String', but got one of type '_Future'". How can I make a request with auth token without that error?
My login function, where I write the token:
loginUser() async {
final storage = new FlutterSecureStorage();
Uri uri = Uri.parse("http://127.0.0.1:8000/api/account/login");
await http
.post(uri,
headers: {"Content-Type": "application/json"},
body: jsonEncode({
"username": emailController.text,
"password": passwordController.text
}))
.then((response) async {
if (response.statusCode == 200) {
var data = json.decode(response.body);
await storage.write(key: "token", value: data["token"]);
print(data["token"]);
} else {
print(json.decode(response.body));
}
});
}
My getdata function, where i use the token:
getdata() async {
final storage = FlutterSecureStorage();
Uri uri = Uri.parse("http://127.0.0.1:8000/api/account/countries");
await http.get(uri, headers: {
"Content-Type": "application/json",
"Authorization": await storage.read(key: "token")
});
}
try this code
String token = await storage.read(key: 'token');
//make sure if there is no Bearer just token in that case just pass the token
var headers = {
'accept': 'application/json',
'Authorization': 'Bearer ${token}',
};
Uri uri = Uri.parse("http://127.0.0.1:8000/api/account/countries");
Response response = await http.get(
uri,
headers: headers
);
print (response);

When I use flutter http library with headers authorization token, its shows 500, in console. but in postman all okay

Here is my code, I also tried using retrofit but I failed and it shows 500 and "message": "Undefined index: token". but in postman, it shows 200. how can it be possible?
Also tried
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token',
Future getCertificateList() async {
final url = Uri.parse(
'https://portal-api.jomakhata.com/api/getCertificateList');
final response = await http.get(url,
headers: {
'Authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI4OTksImlzcyI6Imh0dHBzOi8vcG9ydGFsLWFwaS5qb21ha2hhdGEuY29tL2FwaS9hdXRoL2xvZ2luIiwiaWF0IjoxNjI4NjE0MDcyLCJleHAiOjE2Mjg3MDA0NzIsIm5iZiI6MTYyODYxNDA3MiwianRpIjoiRnRjaGllbTFFdVlsYXZidyJ9.O24U0XGFiZdfXRGUP5xYD82-LisSbMsCtVZnuG6iTiY',
},
);
print(response.statusCode);
print(response.body);
return response.body;
}
In my console it's print 500
this is postman request image
try this code:
Future getCertificateList() async {
final uri = Uri.https('https://portal-api.jomakhata.com','/api/getCertificateList');
final response = await http.get(uri, headers: {
HttpHeaders.authorizationHeader:
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI4OTksImlzcyI6Imh0dHBzOi8vcG9ydGFsLWFwaS5qb21ha2hhdGEuY29tL2FwaS9hdXRoL2xvZ2luIiwiaWF0IjoxNjI4NjE0MDcyLCJleHAiOjE2Mjg3MDA0NzIsIm5iZiI6MTYyODYxNDA3MiwianRpIjoiRnRjaGllbTFFdVlsYXZidyJ9.O24U0XGFiZdfXRGUP5xYD82-LisSbMsCtVZnuG6iTiYv',
HttpHeaders.contentTypeHeader: 'application/json',
});
print(response.statusCode);
print(response.body);
return response.body;
}

Accessing REST API in Flutter with HTTP package

I have a REST API that I need to access from a Flutter app. It is from the Spotify Web API. The terminal command that I would use for this is
curl -X "GET" "https://api.spotify.com/v1/me/following?
type=artist&limit=50" -H "Accept: application/json" -H "Content-Type:
application/json" -H "Authorization: Bearer (ACCESS TOKEN)"
Which works. In Flutter, I have imported the import 'package:http/http.dart' as http package and import 'dart:convert'. I also have a Future that is as follows
Future<String> getData() async {
http.Response response = await http.get(
Uri.https("api.spotify.com", "v1/me/following?type=artist&limit=50"),
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization":
"Bearer (ACCESS TOKEN)"
});
Map dataMap = jsonDecode(response.body);
print(dataMap);
}
This results in {error: {status: 404, message: Service not found}} which is weird since it works perfectly in terminal. What am I doing wrong?
You need to keep it simple. There might some problem related to URL. Try this:
Future<String> getData() async {
http.Response response = await http.get(
"https://api.spotify.com/v1/me/following?type=artist&limit=50",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization":
"Bearer (ACCESS TOKEN)"
});
Map dataMap = jsonDecode(response.body);
print(dataMap);
}
NetService:
class NetService {
static Future<T?> getJson<T>(String url, {int okCode = 200, String? authKey, Map<String, String>? headers}) {
var localHeaders = <String, String>{};
localHeaders['Accept'] = 'application/json';
localHeaders['Content-Type'] = 'application/json';
if (authKey != null) localHeaders['Authorization'] = 'Bearer $authKey';
if (headers != null) localHeaders.addAll(headers);
return http.get(Uri.parse(url), headers: localHeaders)
.then((response) {
if (response.statusCode == okCode) {
return jsonDecode(response.body) as T;
}
PrintService.showDataNotOK(response);
return null;
})
.catchError((err) => PrintService.showError(err));
}
}
Main:
import 'dart:async';
import 'package:_samples2/networking.dart';
class Spotify {
static const _oAuthToken = 'XXXXYYYYYZZZZ';
static const _url = 'https://api.spotify.com/v1';
static FutureOr<void> getUsersFollowedArtists() async {
await NetService.getJson<Map<String, dynamic>>(_url + '/me/following?type=artist&limit=50', authKey: _oAuthToken)
.then((response) => print(response))
.whenComplete(() => print('\nFetching done!'));
}
}
void main(List<String> args) async {
await Spotify.getUsersFollowedArtists();
print('Done.');
}
Result:
{artists: {items: [], next: null, total: 0, cursors: {after: null}, limit: 50, href: https://api.spotify.com/v1/me/following?type=artist&limit=50}}
Fetching done!
Done.

Flutter - How to send a POST request using HTTP in Dart?

I am using an API that converts HTTP to JSON and to get a response from the server I need to send a post request of HTML however i'm not sure how to do that?
This is my current implementation -
Future<String> test() async {
var link =
await http.get('https://example.com');
var body = parse(link.body);
return body.outerHtml;
}
Future<Album> createAlbum(String html) async {
final http.Response response = await http.post(
'https://www.html2json.com/api/v1',
headers: <String, String>{
'Content-Type': 'text/html; charset=UTF-8',
},
body: html,
);
if (response.statusCode == 200) {
return Album.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to create album.');
}
}
I call this is when my app starts like so,
#ovveride
void initState() {
test().then((body) => createAlbum(body)); //Output returns HTTP error 301, am I doing something wrong?
super.initState();
}
Checked the following code which worked for me.
Future<Album> createAlbum(String html) async {
final http.Response response = await http.post(
'https://www.html2json.com/api/v1',
headers: <String, String>{
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
},
body: html,
);
You need to change the Content-type to application/x-www-form-urlencoded; charset=UTF-8. This should do the trick.
Thanks to DARSH SHAH, I solved this using dio (https://pub.dev/packages/dio).
dynamic response;
Dio dio = Dio();
Future<dynamic> test() async {
dynamic link = await dio.get(
'https://example.com');
return link;
}
Future<dynamic> post(dynamic body) async {
String _baseUrl = "https://html2json.com/api/v1";
var options = Options(
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
followRedirects: false,
);
final response = await dio.post(
_baseUrl,
data: body,
options: options,
);
return response;
}
FloatingActionButton(
onPressed: () async {
dynamic responseHTML = await test();
response = await post(responseHTML.data); //This will contain the JSON response
},
);

How to remove quotation and symbols while decoding from JSON value? Flutter

This is the code to get my auth token.
Future <String> getToken() async{
final SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString('token');
}
When i print the token it gives me this json value with double quotation mark.
I/flutter (14710): "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiZDQzZjFjNWZjZDQxYjIzYzllNGU2ZWIyZjQ1M2FmZDgwOTJiNGZmNDAyYjI0OTBmM2RiYTUzMTgzYTU2ODZjNTNiNzVmMDY3ZmIzMmNjMjUiLCJpYXQiOjE1OTA0MDg2NjksIm5iZiI6MTU5MDQwODY2OSwiZXhwIjoxNjIxOTQ0NjY5LCJzdWIiOiIxIiwic2NvcGVzIjpbXX0.3YYdR8P1_XzK--VLAwT5gxmkyLZPMuvQhzQQ5OOl_nv0jriPwFY9sqHdL_wiqpAA5vtgBOnyAwZ2kSI_BgDzsKZzY2vMVa47Tyuz87uEFZ7-aHYvNY_r4T_gIkwAuLwc8qN2kuytFjEtuq-iQUiWgEzp5y2n3BDlzXZ7rZi5Xp1_y_6_ysII9RQtX37LuDFt3AIRbYLGDBAilPHi0iJB_jQqWqH8J1mUzCsArj2VuSel7kERqpwFz-SwOOS4EA7CaoOuOlleOpynBalTK9vm1vU3n81K4TAgNq-Mg9CsiFMVQULURdmku7-2gcc3VS8vBXo9OlEgzqmGjLDvIy8_-LCcwuoSVC2DL2t2PIcNUDKQsBu1GBPQ99wzHcnyEpvjVRkg7v4zQWtlIUY6PcLjNf_vnfuXuCERAwBwjS86T7n8ZscfmVVebISVvAKyDN6YhW41hnUw-AZYRLtuhbE8Z48V0tLfLw9aeVr-Qe2mlaYj0LqGYlqBLqUtRl9HSaA9USa6tQ1KQJvF5_6JPcIBJuSkEsrY9n1xhnCViAiyFVF4XWbtToULn69B2UtoXw1X8y_Wek_T7D7t0fi5KWKj8QHO6yI3ZIWViERS2K6n7mnL_3z_7CNeewVxmqMXNdeWl7yPmAMzUAv6z7pWm-R1Qpv7tNVj4-FfQAk3vOm56hE"
This is how i used the token you get the post from api but it isnt working.
Future<Model> ViewWelcomeScreen() async {
String url = '$baseurl/post/20';
ApiService().getToken().then((value){
token = value;
});
final response = await http.get(url, headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token'
});
print(token);
if (response.statusCode == 200) {
var test = json.decode(response.body);
var jsonResponse = test['data'];
return Model.fromJson(jsonResponse);
} else {
throw Exception('Failed to load data');
}
}
Future<Model> ViewWelcomeScreen() async {
String url = '$baseurl/post/20';
ApiService().getToken().then((value){
token = value;
});
final response = await http.get(url, headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token'
});
print(token);
if (response.statusCode == 200) {
var test = json.decode(response.body);
var jsonResponse = test['data'];
return Model.fromJson(jsonResponse);
} else {
throw Exception('Failed to load data');
}
}
code is wrong in a way, think you have async and then both on the same function, why?
ApiService().getToken().then((value){
token = value;
});
here you're saying I want token and I don't need to be awaited then you go and try to use that variable
final response = await http.get(url, headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token'
});
see in flutter every async-await works like event loop in javascript
I write async
normal code
using then in 1. function
dependent code in 1. as async-await
what will be the output?
event loop will be having 1,2,3,4 as async functions
first, it will run 1 and as soon as it receives normal code it runs normally but if it receives then it will understand that this result is not important so let me do rest of the work and will come back to execute 3rd then function so it will run 4 and then 3rd function
but you want token so
ApiService().getToken().then((value){
token = value;
});
replace this to
token = await ApiService().getToken();
your service might need token and that's the reason it's not 200 status code.
If you just want to remove the "" from the string, then just use the replaceAll method
String string = '"foo"';
//Output: 'foo'
string.replaceAll('"', '');