How to set headers for POST with flutter and Dio - flutter

this is my code below, i'm stuck please help.
void getProducts() async {
String htoken = Utils.prefs.getString("token");
print(htoken);
try {
var dio = Dio(BaseOptions(headers: {"appusertoken": "$htoken"}));
//dio.options.headers["appusertoken"] = "$htoken";
Response response = await dio.post(
'APIURL',
);
print("data coming");
print(response.data);
} on DioError catch (e) {
print(e.response.data);
print(e.response.headers);
print(e.response.request);
}
}
it was throwing an error of data null.

I was able to fix the issues.
Add optional parameter options for dio.post method and define headers with Options class:
void getProducts() async {
String htoken = Utils.prefs.getString("token");
try {
Dio dio = Dio();
Response response = await dio.post("http://URL",
data: {},
options: Options(
headers: {"appusertoken": "$htoken"},
));
print("data coming");
print(response);
} on DioError catch (e) {
print(e.response.data);
print(e.response.headers);
print(e.response.request);
}
}

For example :
Dio _dio = new Dio();
_dio.options.contentType = Headers.formUrlEncodedContentType;
_dio.options.headers['Authorization'] = 'bearer $authToken';
or use :
final Map<String, dynamic> header = {'Authorization': 'bearer $authToken'};
enter code here
final responseData = await _dio.get(
Apis.account_profit,
options: RequestOptions(
method: 'GET', headers: header, baseUrl: Apis.apiBaseUrl),
);

Related

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 - 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 post form data request using flutter in http package

I want to send form data in flutter using the HTTP package. Getting the error:FormatException: Unexpected character (at character 1)
I/flutter (30465):
I am sending the form data in the HTTP post request.
Future<void> authethicate(
String schoolName,
String password,
) async {
try {
final url = 'https://yobimx.com/citykey/api/users/login';
final response = await http.post(url, body: {
'email': 'usamashafiq199#outlook.com',
'password': '123',
}, headers: {
"Content-Type": "application/x-www-form-urlencoded",
});
print(
json.decode(response.body),
);
final responseData = json.decode(response.body);
} catch (error) {
print(error);
}
}
I have to use a multipart request for request. Thanks for your help.
Future<void> authethicate(
String schoolName,
String password,
) async {
try {
final url = Uri.parse('https://yobimx.com/citykey/api/users/login');
Map<String, String> requestBody = <String, String>{
'email': 'usamashafiq199#outlook.com',
'password': '123'
};
var request = http.MultipartRequest('POST', url)
..fields.addAll(requestBody);
var response = await request.send();
final respStr = await response.stream.bytesToString();
print(
jsonDecode(respStr),
);
print("This is the Status Code$respStr");
var encoded = json.decode(respStr);
print(encoded['status']);
print('This is the userId${encoded['data']['user_id']}');
} catch (error) {
print(error);
}
}

Could not set header with dio

I ma not able to set header with dio.I am tryng to set my access token to the header.I ma trying to set header so that every request doesnt required to call it.Here is my network class where i am trying to call header with dio
My network Class:
class NetworkUtil {
Dio _dio;
String token;
getToken() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
String getToken = preferences.getString(AppPrefernces.LOGIN_PREF);
return getToken;
}
NetworkUtil() {
///Create Dio Object using baseOptions set receiveTimeout,connectTimeout
BaseOptions options = BaseOptions(receiveTimeout: 5000, connectTimeout: 5000);
options.baseUrl = ApiConstants.BASE_URL;
_dio = Dio(options);
_dio.interceptors.add(InterceptorsWrapper(
onRequest: (Options option) async{
//my function to recovery token
await getToken().then((result) {
LoginResponse loginResponse = LoginResponse.fromJson(jsonDecode(result));
token = loginResponse.accessToken;
});
option.headers = {
"Authorization": "Bearer $token"
};
}
));
}
///used for calling Get Request
Future<Response> get(String url, Map<String, String> params) async {
Response response = await _dio.get(url,
queryParameters: params,
options: Options(responseType: ResponseType.json));
return response;
}
///used for calling post Request
Future<Response> post(String url, Map<String, String> params) async {
Response response = await _dio.post(url,
data: params, options: Options(responseType: ResponseType.json));
return response;
}
}
I use this setup and it works fine for me.
Future<Dio> createDioWithHeader() async {
if (_dioWithHeader != null) return _dioWithHeader;
String token = await appSharedPreferences.getToken();
String userAgent = await getUserAgent();
print('User-Agent: $userAgent');
// base config
_dioWithHeader = Dio(BaseOptions(
connectTimeout: 10000,
receiveTimeout: 10000,
baseUrl: Config.apiBaseUrl,
contentType: 'application/json',
headers: {
'Authorization': token,
'User-Agent': userAgent
}));
// setup interceptors
return addInterceptors(_dioWithHeader);
}```

How to upload images and file to a server in Flutter?

I use a web service for image processing , it works well in Postman:
Now I want to make http request in flutter with Dart:
import 'package:http/http.dart' as http;
static ocr(File image) async {
var url = '${API_URL}ocr';
var bytes = image.readAsBytesSync();
var response = await http.post(
url,
headers:{ "Content-Type":"multipart/form-data" } ,
body: { "lang":"fas" , "image":bytes},
encoding: Encoding.getByName("utf-8")
);
return response.body;
}
but I don't know how to upload the image file, in above code I get exception: Bad state: Cannot set the body fields of a Request with content-type "multipart/form-data".
How should I write the body of request?
Your workaround should work; many servers will accept application/x-www-form-urlencoded as an alternative (although data is encoded moderately inefficiently).
However, it is possible to use dart:http to do this. Instead of using http.post, you'll want to use a http.MultipartFile object.
From the dart documentation:
var request = new http.MultipartRequest("POST", url);
request.fields['user'] = 'someone#somewhere.com';
request.files.add(http.MultipartFile.fromPath(
'package',
'build/package.tar.gz',
contentType: new MediaType('application', 'x-tar'),
));
request.send().then((response) {
if (response.statusCode == 200) print("Uploaded!");
});
I'd like to recommend dio package to you , dio is a powerful Http client for Dart/Flutter, which supports Interceptors, FormData, Request Cancellation, File Downloading, Timeout etc.
dio is very easy to use, in this case you can:
Sending FormData:
FormData formData = new FormData.from({
"name": "wendux",
"file1": new UploadFileInfo(new File("./upload.jpg"), "upload1.jpg")
});
response = await dio.post("/info", data: formData)
More details please refer to dio。
This can be achieved using the MultipartRequest class (https://pub.dev/documentation/http/latest/http/MultipartRequest-class.html)
Change the media type and uri as needed.
uploadFile() async {
var postUri = Uri.parse("<APIUrl>");
var request = new http.MultipartRequest("POST", postUri);
request.fields['user'] = 'blah';
request.files.add(new http.MultipartFile.fromBytes('file', await File.fromUri("<path/to/file>").readAsBytes(), contentType: new MediaType('image', 'jpeg')))
request.send().then((response) {
if (response.statusCode == 200) print("Uploaded!");
});
}
I found a working example without using any external plugin , this only uses
import 'package:http/http.dart' as http;
import 'dart:io';
import 'package:path/path.dart';
import 'package:async/async.dart';
import 'dart:convert';
Code
var stream =
new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
// get file length
var length = await imageFile.length(); //imageFile is your image file
Map<String, String> headers = {
"Accept": "application/json",
"Authorization": "Bearer " + token
}; // ignore this headers if there is no authentication
// string to uri
var uri = Uri.parse(Constants.BASE_URL + "api endpoint here");
// create multipart request
var request = new http.MultipartRequest("POST", uri);
// multipart that takes file
var multipartFileSign = new http.MultipartFile('profile_pic', stream, length,
filename: basename(imageFile.path));
// add file to multipart
request.files.add(multipartFileSign);
//add headers
request.headers.addAll(headers);
//adding params
request.fields['loginId'] = '12';
request.fields['firstName'] = 'abc';
// request.fields['lastName'] = 'efg';
// send
var response = await request.send();
print(response.statusCode);
// listen for response
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
How to upload image file using restAPI in flutter/dart.
This work for me.
var postUri = Uri.parse("apiUrl");
http.MultipartRequest request = new http.MultipartRequest("POST", postUri);
http.MultipartFile multipartFile = await http.MultipartFile.fromPath(
'file', filePath);
request.files.add(multipartFile);
http.StreamedResponse response = await request.send();
print(response.statusCode);
Updated 2021 way:
using flutter http and mime
import 'package:mime/mime.dart';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'dart:io';
Future<dynamic> multipartImageUpload(String baseUrl, String api, File image) async {
var uri = Uri.parse(baseUrl + api);
final mimeTypeData =
lookupMimeType(image.path, headerBytes: [0xFF, 0xD8]).split('/');
// Intilize the multipart request
final imageUploadRequest = http.MultipartRequest('PUT', uri);
// Attach the file in the request
final file = await http.MultipartFile.fromPath('image', image.path,
contentType: MediaType(mimeTypeData[0], mimeTypeData[1]));
imageUploadRequest.files.add(file);
// add headers if needed
//imageUploadRequest.headers.addAll(<some-headers>);
try {
final streamedResponse = await imageUploadRequest.send();
final response = await http.Response.fromStream(streamedResponse);
return response;
} catch (e) {
print(e);
return null;
}
}
Use MultipartRequest class.
How to upload image file using restAPI in flutter/dart
void uploadImage1(File _image) async {
// open a byteStream
var stream = new http.ByteStream(DelegatingStream.typed(_image.openRead()));
// get file length
var length = await _image.length();
// string to uri
var uri = Uri.parse("enter here upload URL");
// create multipart request
var request = new http.MultipartRequest("POST", uri);
// if you need more parameters to parse, add those like this. i added "user_id". here this "user_id" is a key of the API request
request.fields["user_id"] = "text";
// multipart that takes file.. here this "image_file" is a key of the API request
var multipartFile = new http.MultipartFile('image_file', stream, length, filename: basename(_image.path));
// add file to multipart
request.files.add(multipartFile);
// send request to upload image
await request.send().then((response) async {
// listen for response
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}).catchError((e) {
print(e);
});
}
name spaces:
import 'package:path/path.dart';
import 'package:async/async.dart';
import 'dart:io';
import 'package:http/http.dart' as http;
UPLOAD IMAGE TO SERVER WITH FORM DATA
To upload image to server you need a dio library.
Features:
Authorization (adding token)
Adding extra field like: username, etc
Adding Image to upload
Code example:
import 'package:dio/dio.dart' as dio;
import 'dart:convert';
try {
///[1] CREATING INSTANCE
var dioRequest = dio.Dio();
dioRequest.options.baseUrl = '<YOUR-URL>';
//[2] ADDING TOKEN
dioRequest.options.headers = {
'Authorization': '<IF-YOU-NEED-ADD-TOKEN-HERE>',
'Content-Type': 'application/x-www-form-urlencoded'
};
//[3] ADDING EXTRA INFO
var formData =
new dio.FormData.fromMap({'<SOME-EXTRA-FIELD>': 'username-forexample'});
//[4] ADD IMAGE TO UPLOAD
var file = await dio.MultipartFile.fromFile(image.path,
filename: basename(image.path),
contentType: MediaType("image", basename(image.path)));
formData.files.add(MapEntry('photo', file));
//[5] SEND TO SERVER
var response = await dioRequest.post(
url,
data: formData,
);
final result = json.decode(response.toString())['result'];
} catch (err) {
print('ERROR $err');
}
To add a header and use http multipart with https://pub.dev/packages/multi_image_picker Plugin,
This is the code.
var request = http.MultipartRequest(
'POST', Uri.parse(myurl)
);
//Header....
request.headers['Authorization'] ='bearer $authorizationToken';
request.fields['PropertyName'] = propertyName;
request.fields['Country'] = country.toString();
request.fields['Description'] = des;
request.fields['State'] = state.toString();
request.files.add(http.MultipartFile.fromBytes(
'ImagePaths',
learnImage,
filename: 'some-file-name.jpg',
contentType: MediaType("image", "jpg"),
)
);
var response = await request.send();
print(response.stream);
print(response.statusCode);
final res = await http.Response.fromStream(response);
print(res.body);
To use HTTP and https://pub.dev/packages/image_picker PLUGIN
This is the code
var request = http.MultipartRequest(
'POST', Uri.parse(myurl)
);
request.headers['Authorization'] ='bearer $authorizationToken';
request.fields['PropertyName'] = propertyName;
request.fields['Country'] = country.toString();
request.fields['Description'] = des;
request.fields['State'] = state.toString();
request.files.add(await http.MultipartFile.fromPath(
'ImagePaths',
file.path
)
);
var response = await request.send();
print(response.stream);
print(response.statusCode);
final res = await http.Response.fromStream(response);
print(res.body);
Working Code
String path = userSelectedImagePath;
Map<String, String> data = {
"name": firstName!,
"email": userEmail!
};
String token = await LocaldbHelper().getToken();
Map<String, String> headers = {
'X-Requested-With': 'XMLHttpRequest',
'authorization': 'Bearer $token',
};
var request = http.MultipartRequest(
'POST',
Uri.parse(ApiUrl.updateProfile),
);
request.fields.addAll(data);
request.headers.addAll(headers);
var multipartFile = await http.MultipartFile.fromPath(
'avatar', path); //returns a Future<MultipartFile>
request.files.add(multipartFile);
http.StreamedResponse response = await request.send();
final respStr = await response.stream.bytesToString();
var jsonData = jsonDecode(respStr);
if (response.statusCode == 200) {
// success
} else {
// error
}
Just leaving this here, if anyone is trying to upload a pdf or any other document using MultipartRequest method.
Just add the content type as -
contentType: new MediaType('application', 'pdf')
Good code with Dio and FilePicker for post file on your server. I use flutter for the web.
FilePicker
Dio
First you need writing Dio post method.
Future postImportClient(PlatformFile file) async {
try {
var urlBase = 'your url';
var mfile = MultipartFile.fromBytes(file.bytes!, filename: file.name);
var formData = FormData();
formData.files.add(MapEntry('file', mfile));
await _dio.post(urlBase, data: formData);
} on DioError catch (error) {
throw Exception(error);
}
}
Initial FilePicker and get file.
FilePickerResult? result = await FilePickerWeb.platform.pickFiles();
if (result != null) {
var file = result.files.single;
await client.postImportClient(file);
}
Good luck!
create FormData:
final formDataMap = <String, dynamic>{};
formDataMap["stringKey"] = "string";
List<MultipartFile> multipartImageList = [];
await Future.forEach(imagePaths as List<String>,(String path) async {
final multiPartFile = await MultipartFile.fromFile(
path,
contentType: MediaType("image", "jpeg"),
);
multipartImageList.add(multiPartFile);
});
formDataMap["image[]"] = multipartImageList;
final formData = FormData.fromMap(formDataMap);
With Retrofit & Dio:
#MultiPart()
#POST("{{url}}")
Future<dynamic> uploadFormData(
#Body() FormData formData,
);
With Hearder
upload image
Future uploadImageMedia(File fileImage, String token) async {
final mimeTypeData =
lookupMimeType(fileImage.path, headerBytes: [0xFF, 0xD8]).split('/');
final imageUploadRequest =
http.MultipartRequest('POST', Uri.parse(mainUrlSite + "wp-json/wp/v2/media"));
final file = await http.MultipartFile.fromPath('file', fileImage.path,
contentType: MediaType(mimeTypeData[0], mimeTypeData[1]));
imageUploadRequest.files.add(file);
imageUploadRequest.headers.addAll({
"Authorization": "Bearer " + token
});
try {
final streamedResponse = await imageUploadRequest.send();
streamedResponse.stream.transform(utf8.decoder).listen((value) {
print(value);
return Future.value(value);
});
} catch (e) {
print(e);
}
}
I use Dio library with put method:
var formData = FormData.fromMap({
'simpleParam': 'example',
'file': await MultipartFile.fromFile(filePath, filename: 'file.jpg')
});
var dio = Dio();
dio.options.headers[HttpHeaders.authorizationHeader] = myToken;
var response = new Response(); //Response from Dio
response = await dio.put(myUrl + "/myApi", data: formData);
The result is in response.data
try {
result[HttpKeys.status] = false;
var request = http.MultipartRequest('POST', url);
request.fields.addAll(body);
if (avatar.path.isNotEmpty) {
request.files.add(await http.MultipartFile.fromPath('uploadedImg', avatar.path));
}
request.headers.addAll(headers);
http.StreamedResponse streamResponse = await request.send();
final response = await http.Response.fromStream(streamResponse);
if (response.statusCode == 200) {
var resMap = jsonDecode(response.body);
debugPrint('<== π•Šπ•šπ•˜π•Ÿ 𝕦𝕑 𝕀𝕦𝕔𝕔𝕖𝕀𝕀𝕗𝕦𝕝𝕝π•ͺ ==>');
// debugPrint(response.body);
result[HttpKeys.status] = true;
result[HttpKeys.message] = resMap[HttpKeys.message];
result[HttpKeys.data] = resMap['data'];
return result;
} else {
var resMap = jsonDecode(response.body);
result[HttpKeys.message] = resMap[HttpKeys.message];
return result;
}
} catch (error) {
result[HttpKeys.message] = error.toString();
return result;
}
Here is the code where I am passing Image, route which may be like '/register', and data which is Map<String, String> like data={'directory':'profile'}.
For Uploading Image to Laravel API, Authorization in header is compulsory otherwise it would return "You don't have permission to access this resource". I am passing token as EMPTY string like String token='' as I am uploading
Image at user registration time
This Authorization for read and write is defined in domainurl/public/.htaccess file, you can change it
Try to understand the below code and all the issue would be resolve.
Future uploadImage({
required XFile file,
required String route,
required Map<String, String> data,
}) async {
String url = API_Url + route;
final uri = Uri.parse(url);
try {
http.MultipartRequest request = http.MultipartRequest("POST", uri);
http.MultipartFile multipartFile =
await http.MultipartFile.fromPath('image', file.path);
request.files.add(multipartFile);
request.headers.addAll(_header());
request.fields.addAll(data);
var streamedResponse = await request.send();
var response = await http.Response.fromStream(streamedResponse);
print(jsonDecode(response.body));
return jsonDecode(response.body);
} catch (e) {
return null;
}
}
_header() {
return {"Content-Type": "multipart/form-data",
'Authorization': 'Bearer ${token}',
};
}
With dio I do like this:
Future<void> _uploadFileAsFormData(String path) async {
try {
final dio = Dio();
dio.options.headers = {
'Content-Type': 'application/x-www-form-urlencoded'
};
final file =
await MultipartFile.fromFile(path, filename: 'test_file');
final formData = FormData.fromMap({'file': file}); // 'file' - this is an api key, can be different
final response = await dio.put( // or dio.post
uploadFileUrlAsString,
data: formData,
);
} catch (err) {
print('uploading error: $err');
}
}