How to make API call in flutter with header key? - flutter

Suppose the host site is: :
https://dev.xyz.com
API header key: "x-api-key: 7462-3172-8773-3312-5819"
To register a new user you have to call PUT method: {{host}}/api/customer/
And the body is like this:
{"email": "test#example.net",
"password": "aabbccdd",
"Name": "John",
}
Now how do I accomplish this in flutter? I have searched through several tutorials and still in confusion.

Import the http package from dart library and alias it as http, reason for this aliasing is that you dont want to have .get() method suggestion everywhere in the file. So when you use it with http as http.get() it will give you suggestion for get, In which you can pass the parameter called headers.
Code goes as follows:
import 'package:http/http.dart' as http;
url = 'YOUR_URL';
var response = await http.get(
url,
headers: {HttpHeaders.authorizationHeader: TOKEN}, //an example header
);
In your case,
import 'dart:convert';
import 'dart:io';
import 'dart:async';
main() async {
String url =
'https://dev.xyz.com';
Map map = {
'data': {'apikey': '7462-3172-8773-3312-5819'},
};
print(await apiRequest(url, map));
}
Future<String> apiRequest(String url, Map jsonMap) async {
HttpClient httpClient = new HttpClient();
HttpClientRequest request = await httpClient.postUrl(Uri.parse(url));
request.headers.set('content-type', 'application/json');
request.add(utf8.encode(json.encode(jsonMap)));
HttpClientResponse response = await request.close();
// todo - you should check the response.statusCode
String reply = await response.transform(utf8.decoder).join();
httpClient.close();
return reply;
}

You need put the header on the http request. For example:
await put(urlApi + 'update/'+ customer.id, headers: {'token': token, 'content-type': 'application/json'},body: body);

Related

how to send a GET request with Json body in Flutter?

I need to send a GET HTTP request with a JSON body. I know that this is not allowed by the RestFul specs. However, there is no chance to change the server. Is there a way to overcome this restriction in Flutter?
This is the code I am trying to use but I couldn't find a way to insert the body.
String urlGetkey = "https://pa.me/transactions/card_hash_key";
Map userHeader = {
"Content-type": "application/json",
"Accept": "application/json",
"User-Agent": "curl/7.64.",
};
var _body = jsonEncode({"api_key": zulu});
var request = http.Request('GET', Uri.parse(urlGetkey));
request.body = _body;
final streamedResponse = await request.send();
var response = await http.Response.fromStream(streamedResponse);
'''
Thanks in advance
You are close, but you need to use a subclass of BaseRequest so that you can add the body, which you can do by grabbing its sink and adding the body to that before then sending the request.
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() async {
final payload = '{"api_key":"ak_test_46po64VBDm3aqJmR8oXvFLqQi0VxtP"}';
final request = http.StreamedRequest(
'GET',
Uri.https(
'api.pagar.me',
'/1/transactions/card_hash_key',
),
);
request.headers['content-type'] = 'application/json';
request.sink
..add(utf8.encode(payload))
..close();
final streamedResponse = await request.send();
final response = await http.Response.fromStream(streamedResponse);
print(response.statusCode);
print(response.body);
}

api calls - Flutter

I'm trying to make a api call but I can't success, everything goes fine until the call, and there stop everything and the function finish, what I do wrong?
Future<String> get() async {
var url = Uri.parse("https://10.0.2.2:7021/api/Auth/login");
var headers = {"content-type": "application/json"};
final msg = jsonEncode(
{"username": "string", "password": "string", "email": "string"});
var response = await http!.post(url, body: msg, headers: headers);
if (response.statusCode == 200) {
var data = jsonDecode(response.body);
print("Correct");
return "Correct";
} else {
print(response.statusCode);
print("User not allowed");
throw Exception("User not allowed");
}
}
Mistake comes here
debug window
You have probably imported the "wrong" http. Do it like that:
import 'package:http/http.dart' as http;
You dont need to write http! because http is a package and is never null and since you are doing http! I guess you imported something wrong in your code.
EDIT:
Maybe your device can't reach 10.0.2.2 (or that port), you should set a timeout to find it out fast:
http.post(url, body: msg, headers: headers).timeout(
const Duration(seconds: 3),
onTimeout: () {
// request timed out
return http.Response('Error', 408);
},
);
Have you imported http package like this?
import 'package:http/http.dart' as http;
And use case like this
var response = await http.post(url, body: msg, headers: headers);
add .php to login in the url :
https://10.0.2.2:7021/api/Auth/login.php
if you are working with php
or .py for python

DioError [DioErrorType.RESPONSE]: Http status error [404]

Postman form-data request
Request body containing
Expected Response body
Dio Flutter code
import 'package:dio/dio.dart';
import 'package:flutter_project/config/config.dart';
import '../model/postImage.dart';
import 'dart:io';
Future<PostImage> postImage(File image) async{
String fileName = image.path.split('/').last;
print(fileName);
try{
Dio dio = new Dio();
FormData formData = FormData.fromMap({
"file": await MultipartFile.fromFile(image.path,filename: fileName)
});
Map<String, String> headers= <String,String>{
'Content-Type':'multipart/form-data'
};
print("${baseURL}files/upload");
Response response = await dio.post("${baseURL}files/upload",data: formData);
if(response.statusCode == 200){
print("Uploaded");
}
else{
print(response.data);
}
}
catch(e){
print(e);
}
}
Expection that I am getting : DioError [DioErrorType.RESPONSE]: Http status error [404]
I added contentType: new MediaType("image", "jpeg")//in the formData. It works now.
Full Code :
import 'package:dio/dio.dart';
import 'package:flutter_project/config/config.dart';
import '../model/postImage.dart';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
Future<PostImage> postImage(File image) async {
String fileName = image.path.split('/').last;
print(fileName);
try {
Dio dio = new Dio();
FormData formData = FormData.fromMap({
"file": await MultipartFile.fromFile(
image.path,
filename: fileName,
contentType: new MediaType("image", "jpeg"),
)
});
Map<String, String> headers = <String, String>{
'Content-Type': 'multipart/form-data'
};
print("${baseURL}files/upload");
Response response =
await dio.post("${baseURL}files/upload", data: formData);
if (response.statusCode == 200) {
print("Uploaded");
} else {
print(response.data);
}
print('Out');
} catch (e) {
print(e);
}
}
When I encountered an HTTP 4xx error while using Dio and I was sure I had my Authorization set, what I did to make it work is to set the Options() parameter explicitly. Precisely, I set the method type (for a get request) and authorisation token like this: Dio().get(url, options: Options(method: "GET", headers: { "Authorization": "Bearer ${LocalStorage().getString(Keys.token)}", })));.
You can also set content-type if need be. To make it easier, you can simply copy-paste into the headers: argument, some of the header values set in/by your postman when you make the same request using postman.

Invalid Header Name In Flutter HTTP Request

I have a login page where i am trying to send a login request to my backend. But I get an Unhandled Exception: Invalid header field name. Here is my submit function
submit() async {
var res = await LoginAPI().loginData(
{'email': _emailController.value, 'password': _passwordController.value});
var body = json.decode(res.body);
print(body);
}
Then in my LoginAPI class here is my loginData function that makes the call to the backend
import 'dart:convert';
import 'package:http/http.dart' as http;
class LoginAPI {
final String _url = "http://10.0.2.2:8000/api/";
Map<String, String> headers = {"Content-type": "application/json"};
loginData(data) async {
var fullUrl = _url + "v1/users/login";
return await http.post(
fullUrl,
body: jsonEncode(data),
headers: headers
);
}
}
Here is my request through postman
Here is my response through postman
When I make the same request with Postman i get the response I am supposed to get. What Am i doing wrong?
try this
Map<String, String> headers = {"Content-type": "application/json", "Accept": "application/json",};
It looks from your postman request that you are just sending form data (not a json encoded body). package:http will form encode the body for you (and add the content type header) if you do the following:
return await http.post(
fullUrl,
body: data,
);
So i was able to solve the issue. The issue was with my CORS middleware on my server. I just made some changes and it worked fine. So if anyone has this issue just know it has nothing to do with flutter but most probably CORS

How to connect api in laravel of flutter apps?

How can I connect my flutter apps with laravel api? Below is what I post in postman.
http://10.0.2.2/voyce/api/register
I try to run the API in postman and it does not give any response.
here is my api.dart in flutter.
api.dart
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
class CallApi{
final String _url = 'http://10.0.2.2/voyce/api/';
postData(data, apiUrl) async {
var fullUrl = _url + apiUrl + await _getToken();
return await http.post(
fullUrl,
body: jsonEncode(data),
headers: _setHeaders()
);
}
getData(apiUrl) async {
var fullUrl = _url + apiUrl + await _getToken();
return await http.get(
fullUrl,
headers: _setHeaders()
);
}
_setHeaders() => {
'Content-type' : 'application/json',
'Accept' : 'application/json',
};
_getToken() async {
SharedPreferences localStorage = await
SharedPreferences.getInstance();
var token = localStorage.getString('token');
return '?token=$token';
}
}
All I want it to make the api able to connect? I think maybe there is something wrong with my laravel API but I dont have any idea where to fix it.
If you've encounter the error SocketException: OS Error: Connection refused, this is most likely a network connection error. When trying to post the url in the browser and you get the proper response, then the problem could be in the postman. But you can refer here for more details on how to integrate Laravel in Flutter.