How to upload image to server in flutter - flutter

How does uploading image to server works in flutter! The ImagePicker return a path to directory,what url should be sent to server and what url should be used to show image on app if I want to upload a png format with autorization token in form-data with key profile_image and to show the similar Image.Below is one of the multiple I tried..
asyncFileUpload(File file) async {
var request = http.MultipartRequest(
"POST",
_getUri(
'/profilepicture',
));
var token = getHeaders();
request.headers["authorization"] = token as String;
;
var pic = await http.MultipartFile.fromPath("profile_image", file.path);
request.files.add(pic);
var response = await request.send();
var responseData = await response.stream.toBytes();
var responseString = String.fromCharCodes(responseData);
print(responseString);
}

What you are sending to the server is .png file and what is supposed to be shown to the user is the image in the server(url path) not the url path from phone. Therefore if the response returns that url all you need to do is get hold of it in the NetworkImage('url') or Image.network('url')
Note: It would be easy if you first show the picked image in your view then have a button that does the submit to the server. If successful replace the image picked url with the url from the server
asyncFileUpload(File file) async {
try {
var request = http.MultipartRequest(
'POST',Uri.parse('url'));
var token = getHeaders();
request.headers["authorization"] = token as String;
request.headers.addAll({
'Content-Type': 'application/json'
});
//request.fields.addAll({
// 'user_id': userId,
//});
request.files.add(await http.MultipartFile.fromPath('profile_image',file.path));
var response = await request.send();
var serverResponse = await http.Response.fromStream(response);
final responseData = json.decode(serverResponse.body);
if(response.statusCode == 200 || response.statusCode == 201){
return responseData;
}else{
return responseData;
}
} catch (e) {
print("Error occurred: $e");
return Future.error(e);
}
}

Related

Flutter : get the original link of shorten url

I have to fetch some url link, but the link is shorten like "shorturl.at/cpqCE".
I want to get the original link url in flutter.
How can I do this?
in Phph I found this :
function expandShortUrl($url) {
$headers = get_headers($url, 1);
return $headers['Location'];
}
// will echo https://deluxeblogtips.com
echo expandShortUrl($url);
Thanks to #RandalSchwartz I solved it by using :
getUrl(url) async {
final client = HttpClient();
var uri = Uri.parse(url);
var request = await client.getUrl(uri);
request.followRedirects = false;
var response = await request.close();
while (response.isRedirect) {
response.drain();
final location = response.headers.value(HttpHeaders.locationHeader);
if (location != null) {
uri = uri.resolve(location);
request = await client.getUrl(uri);
// Set the body or headers as desired.
if (location.toString().contains('https://www.xxxxx.com')) {
return location.toString();
}
request.followRedirects = false;
response = await request.close();
}
}
}
you can also do it by just sending a normal post request with the short link and you will then get the response which includes the original/full URL.
e.g
var uri = Uri.parse(shortUrl);
try {
var response = await http.post(
uri,
headers: {"Accept": 'application/json'},
);
// with below code you get the full path of a short url
String fullPath = response.headers.entries.firstWhere((element) => element.key == "location").value;
print(fullPath);
} catch (e) {
print(e);
}
hope this can help your problem.

How to upload multiple Images through Api

I am trying to Upload Multiple Images through Api but i am not understanding how to send a list, I can upload a single image though. Tried alot of searches but does'nt helped, i also import multi_image_picker i can pick the images but the problem is in uploading.
Future<Map<String, dynamic>> _uploadImage(File image) async {
String value = '';
SharedPreferences pref2 = await SharedPreferences.getInstance();
value = pref2.getString("user_role");
final mimeTypeData =
lookupMimeType(image.path, headerBytes: [0xFF, 0xD8]).split('/');
// Intilize the multipart request
final imageUploadRequest = http.MultipartRequest('POST', apiUrl);
// Attach the file in the request
final file = await http.MultipartFile.fromPath('photo', image.path,
contentType: MediaType(mimeTypeData[0], mimeTypeData[1]));
// Explicitly pass the extension of the image with request body
// Since image_picker has some bugs due which it mixes up
// image extension with file name like this filenamejpge
// Which creates some problem at the server side to manage
// or verify the file extension
imageUploadRequest.files.add(file);
imageUploadRequest.fields['mobile'] = _mobileNo.text;
imageUploadRequest.headers.addAll({
'Content-Type': 'application/json',
'Authorization': Constants.authToken,
});
var response = await imageUploadRequest.send();
if (response.statusCode == 200) print('Done!');
final respStr = await response.stream.bytesToString();
return json.decode(respStr);
}
this an example of uploading files to your API with HTTP package
import 'package:http/http.dart' as http;
void uploadFiles(List<File> files) async {
final url = YOUR-API-LINK;
for (var file in files) {
// Create a multipart request
var request = http.MultipartRequest('POST', Uri.parse(url));
// Add the file to the request
request.files.add(http.MultipartFile.fromBytes(
'file',
file.readAsBytesSync(),
filename: file.path.split('/').last,
));
// Send the request
var response = await request.send();
// Check the status code
if (response.statusCode != 200) {
print('Failed to upload file');
}else{
print response.body;
}
}
}
for Dio use this
void uploadFiles(List<File> files) async {
final url = YOUR-API-LINK;
// Create a Dio client
var dio = Dio();
// Create a FormData object
var formData = FormData();
// Add the files to the FormData object
for (var file in files) {
formData.files.add(MapEntry(
'file',
await MultipartFile.fromFile(file.path, filename: file.path.split('/').last),
));
}
// Send the request
var response = await dio.post(url, data: formData);
// Check the status code
if (response.statusCode != 200) {
print('Failed to upload files');
}else {
print(response.data)
}
}
as you can see there not much difference between them in http you use MultipartRequest in dio you use FormData.

How to upload image to server API with Flutter [duplicate]

This question already has an answer here:
Upload image with http.post and registration form in Flutter?
(1 answer)
Closed 3 years ago.
I am new to Flutter development. My problem is that I try to upload the image but I keep getting failed request.
This piece of code is where I connect it with a server API which will receive the image file from Flutter. String attachment which consist of the image path that is passed from createIncident function located at another page.
Future<IncidentCreateResponse> createIncident( String requesterName, String requesterEmail,
String requesterMobile, String attachment, String title,
String tags, String body, String teamId,
String address ) async {
IncidentCreateResponse incidentCreateResponse;
var url = GlobalConfig.API_BASE_HANDESK + GlobalConfig.API_INCIDENT_CREATE_TICKETS;
var token = Auth().loginSession.accessToken;
var postBody = new Map<String, dynamic>();
postBody["requester_name"] = requesterName;
postBody["requester_email"] = requesterEmail;
postBody["requester_mobile_no"] = requesterMobile;
postBody["attachment"] = attachment;
postBody["title"] = title;
postBody["tags"] = tags;
postBody["body"] = body;
postBody["teamId"] = teamId;
postBody["address"] = address;
// Await the http get response, then decode the json-formatted responce.
var response = await http.post(
url,
body: postBody,
headers: {
'X-APP-ID': GlobalConfig.APP_ID,
"Accept": "application/json; charset=UTF-8",
// "Content-Type": "application/x-www-form-urlencoded",
HttpHeaders.authorizationHeader: 'Bearer $token',
'token': GlobalConfig.API_INCIDENT_REPORT_TOKEN
}
);
if ((response.statusCode == 200) || (response.statusCode == 201)) {
print(response.body);
var data = json.decode(response.body);
incidentCreateResponse = IncidentCreateResponse.fromJson(data['data']);
} else {
print("createIncident failed with status: ${response.statusCode}.");
incidentCreateResponse = null;
}
return incidentCreateResponse;
}
This is the code snippet where I get the image path from the selected image from the gallery
Future getImageFromGallery(BuildContext context) async {
var picture = await ImagePicker.pickImage(source: ImageSource.gallery);
setState((){
_imageFile = picture;
attachment = basename(_imageFile.path);
});
Navigator.of(context).pop();
}
This is the code where I passed the attachment string to the HTTP Response
this.incidentService.createIncident(
Auth().loginSession.name,
Auth().loginSession.email,
Auth().loginSession.mobile_no,
this.attachment,
this._titleController.text,
this._tags,
this._contentController.text,
this._teamId,
this._addressController.text
).then((IncidentCreateResponse res) {
if (res != null) {
print('Ticket Id: ' + res.id);
// Navigator.pop(context);
this._successSubmittionDialog(context);
} else {
this._errorSubmittionDialog(context);
}
}
You can upload image using multipart or base64 Encode.
For uploading image using multipart Visit the Official documentation
For uploading image using base64 Encode you can checkout the Tutorial Here
I suggest using multipart image upload as it is even reliable when your image or files are larger in size.
Hope this could help you,
create a function to upload your image after picking or clicking an image like,
Future<ResponseModel> uploadPhoto(
String _token,
File _image,
String _path,
) async {
Dio dio = new Dio();
FormData _formdata = new FormData();
_formdata.add("photo", new UploadFileInfo(_image, _path));
final response = await dio.post(
baseUrl + '/image/upload',
data: _formdata,
options: Options(
method: 'POST',
headers: {
authTokenHeader: _token,
},
responseType: ResponseType.json,
),
);
if (response.statusCode == 200 || response.statusCode == 500) {
return ResponseModel.fromJson(json.decode(response.toString()));
} else {
throw Exception('Failed to upload!');
}
}
then you can use use uploadImage,
uploadImage(_token, _image,_image.uri.toFilePath()).then((ResponseModel response) {
//do something with the response
});
I have used Dio for the task, you can find more detail about dio here
Add this to your package's pubspec.yaml file:
dependencies:
dio: ^3.0.5
Then import it in your Dart code, you can use:
import 'package:dio/dio.dart';
To upload image using multipart API use this code ie
Add this library dio in your project in pubspec.yaml file
dio: ^3.0.5
and import this in your class
import 'package:dio/dio.dart';
Declare this variable in your class like State<CustomClass>
static var uri = "BASE_URL_HERE";
static BaseOptions options = BaseOptions(
baseUrl: uri,
responseType: ResponseType.plain,
connectTimeout: 30000,
receiveTimeout: 30000,
validateStatus: (code) {
if (code >= 200) {
return true;
}
});
static Dio dio = Dio(options);
then use this method to upload file
Future<dynamic> _uploadFile() async {
try {
Options options = Options(
//contentType: ContentType.parse('application/json'), // only for json type api
);
var directory = await getExternalStorageDirectory(); // directory path
final path = await directory.path; // path of the directory
Response response = await dio.post('/update_profile',
data: FormData.from({
"param_key": "value",
"param2_key": "value",
"param3_key": "value",
"profile_pic_param_key": UploadFileInfo(File("$path/pic.jpg"), "pic.jpg"),
}),
options: options);
setState(() {
isLoading = false;
});
if (response.statusCode == 200 || response.statusCode == 201) {
var responseJson = json.decode(response.data);
return responseJson;
} else if (response.statusCode == 401) {
print(' response code 401');
throw Exception("Incorrect Email/Password");
} else
throw Exception('Authentication Error');
} on DioError catch (exception) {
if (exception == null ||
exception.toString().contains('SocketException')) {
throw Exception("Network Error");
} else if (exception.type == DioErrorType.RECEIVE_TIMEOUT ||
exception.type == DioErrorType.CONNECT_TIMEOUT) {
throw Exception(
"Could'nt connect, please ensure you have a stable network.");
} else {
return null;
}
}
}

How do I upload image in Flutter App to my server and decode the json response from the server?

I have an Endpoint on my server which accepts multipart/form-data and sends back json as a response.
I want to send an Image from my flutter App to my server and Decode the json received from the server.
You can use http.MultipartRequest for that
Example:-
static Future<UploadImageRes> uploadImage(int id, File imageFile) async {
if (imageFile != null) {
var stream = new http.ByteStream(imageFile.openRead());
var length = await imageFile.length();
String token = PreferenceUtils.getString(AppConstants.LOGGED_IN);
var uri = Uri.parse(UrlConstants.ADD_RECIPE_PHOTO);
LogUtils.d("====uri : $uri");
LogUtils.d("====recipeId : $id");
var request = new http.MultipartRequest("POST", uri);
String fileName = imageFile.path.split("/").last;
var multipartFile = new http.MultipartFile('photo', stream, length,
filename: fileName, contentType: new MediaType('image', 'jpeg'));
request.headers.addAll({"Authorization": "Bearer $token"});
request.files.add(multipartFile);
request.fields["recipeId"] = "$id";
var response = await request.send();
var statusCode = response.statusCode;
LogUtils.d("====statusCode : $statusCode");
if (statusCode < 200 || statusCode >= 400) {
throw new ApiException("Uploading failed");
}
final respStr = await response.stream.bytesToString();
return Future.value(UploadImageRes.fromJson(JsonDecoder().convert(respStr)));
} else {
throw new ApiException("Uploading failed");
}
}
In final respStr = await response.stream.bytesToString(); you will get your api response

how to upload image to rest API in flutter through http post method?

I'm trying to upload an image through the flutter via post method. and I'm using image_picker for pick file from mobile but I can't able to upload
and I have tried to send the file like FormData that also doesn't work
Future<dynamic> uploadLicence(int id ,dynamic obj) async {
FormData formdata = new FormData(); // just like JS
formdata.add("image",obj);
final response = await post('Logistic/driver/LicenceImage?
driverId=$id',
formdata);
print(response);
// return null;
if (response.statusCode == 200) {
final result = json.decode(response.body);
return result;
} else {
return null;
}
}
after that, I just tried with this method but this also not working
Future<dynamic> uploadLicence(int id, File file) async {
final url = Uri.parse('$BASE_URL/Logistic/driver/LicenceImage?
driverId=$id');
final fileName = path.basename(file.path);
final bytes = await compute(compress, file.readAsBytesSync());
var request = http.MultipartRequest('POST', url)
..files.add(new http.MultipartFile.fromBytes(
'image',bytes,filename: fileName,);
var response = await request.send();
var decoded = await
response.stream.bytesToString().then(json.decode);
if (response.statusCode == HttpStatus.OK) {
print("image uploded $decoded");
} else {
print("image uplod failed ");
}
}
List<int> compress(List<int> bytes) {
var image = img.decodeImage(bytes);
var resize = img.copyResize(image);
return img.encodePng(resize, level: 1);
}
It's possible with MultipartRequest. Or you can use simply dio package. It's one command.
With http:
import 'package:http/http.dart' as http;
final Uri uri = Uri.parse(url);
final http.MultipartRequest request = http.MultipartRequest("POST", uri);
// Additional key-values here
request.fields['sample'] = variable;
// Adding the file, field is the key for file and file is the value
request.files.add(http.MultipartFile.fromBytes(
field, await file.readAsBytes(), filename: filename);
// progress track of uploading process
final http.StreamedResponse response = await request.send();
print('statusCode => ${response.statusCode}');
// checking response data
Map<String, dynamic> data;
await for (String s in response.stream.transform(utf8.decoder)) {
data = jsonDecode(s);
print('data: $data');
}
I user this code for my project i hope work for you
Upload(File imageFile) async {
var stream = new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
var length = await imageFile.length();
var uri = Uri.parse(uploadURL);
var request = new http.MultipartRequest("POST", uri);
var multipartFile = new http.MultipartFile('file', stream, length,
filename: basename(imageFile.path));
//contentType: new MediaType('image', 'png'));
request.files.add(multipartFile);
var response = await request.send();
print(response.statusCode);
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}