angular get image data and again append it to FormData - javascript

In angular 5 I am getting the images for hotelgallery from mongodb through my service. So basically the data what I am getting is like this
{
fieldname: "hotelgallery",
originalname: "e.jpg",
encoding: "7bit",
mimetype: "image/jpeg",
destination: "./public/",
encoding : "7bit",
filename : "1521139307413.jpg"
mimetype : "image/jpeg"
path : "public/1521139307413.jpg"
size : 66474
}
{
fieldname: "hotelgallery",
originalname: "e.jpg",
encoding: "7bit",
mimetype: "image/jpeg",
destination: "./public/",
encoding : "7bit",
filename : "1521139307413.jpg"
mimetype : "image/jpeg"
path : "public/1521139307413.jpg"
size : 66474
}
{
fieldname: "hotelgallery",
originalname: "j.jpg",
encoding: "7bit",
mimetype: "image/jpeg",
destination: "./public/",
encoding : "7bit",
filename : "1526753678390.jpg"
mimetype : "image/jpeg"
path : "public/1526753678390.jpg"
size : 66470
}
{
fieldname: "hotelgallery",
originalname: "k.jpg",
encoding: "7bit",
mimetype: "image/jpeg",
destination: "./public/",
encoding : "7bit",
filename : "7865456789413.jpg"
mimetype : "image/jpeg"
path : "public/7865456789413.jpg"
size : 66300
}
Now I want to again append those data to FormData but its not working.
The code what I have done so far
export class HotelEditComponent implements OnInit {
formData = new FormData();
ngOnInit() {
this.getOneHotel(this.route.snapshot.params['id']);
}
getOneHotel(id) {
this.http.get( this.apiUrl + '/api/hotel/' + id).subscribe(data => {
this.hotel = data;
this.appendImages(data['hotelimages']); //Here I am getting the data as mentioned here
});
}
public appendImages(imagedata) {
for (var i = 0; i < imagedata.length; i++) {
console.log(imagedata[i]);
this.formData.append('hotelgallery', imagedata[i], imagedata[i]['originalname']);
}
console.log(this.formData);
}
}
So can someone tell me how can I append the existing image data to FormData? Any help and suggestions will be really appreciable.
UseCase for this:
Actually I had used formData to upload images in angular. Now in the edit page the images are showing fine. But lets say a user edits some data and upload some images or remove some images. In that case I am getting the images from the database and again trying to upload them with formdata.
I have used this module and multer for nodejs to upload images with formData.

So can someone tell me how can I append the existing image data to FormData? Any help and suggestions will be really appreciable.
Actually, this approach need more add script solution. for example
1. Get Image Blob from server
Since you return detail object of images, not with the blob. You need have a endpoint to return as blob. (or if return as data buffer then it transform to blob you can use BlobUtil)
2. Put Blob to append form data
You need use blob to append in param 2 no a path, see documentation.
name
The name of the field whose data is contained in value.
value
The field's value. This can be a USVString or Blob (including subclasses
such as File).
filename Optional
The filename reported to the server
(a USVString), when a Blob or File is passed as the second parameter.
The default filename for Blob objects is "blob". The default filename
for File objects is the file's filename.
That what you need, but that is bad practice.
Let's say, you have 30 images to edit, then you need request blob endpoint to get those images blob to appends. But user only want to update 1 image, wasting time to request image blob, right?
For edit image usually we don't need append to file form (<input type="file" />).
Just show it as thumbnail to see what image uploaded and let file form empty.
What we do usually, thumbnail that image.
When user what to change, user put new image and replace old image with new want and update database.
if not, do nothing for image. (YAGNI)

FormData's append is silently failing here. You need to attach the 'image' as a blob. See the MDN docs.
formData.append('hotelgallery', new Blob([imagedata[i]], { type: "text/xml"}), imagedata[i]['originalname']);
Also, just printing formData won't show anything, instead try:
console.log(this.formData.getAll('hotelgallery'));
or
for (var value of this.formData.values()) {
console.log(value);
}

But lets say a user edits some data and upload some images or remove
some images. In that case I am getting the images from the database
and again trying to upload them with formdata.
So, you can pass object to universal method and on result get formData. Object data even can contain nested objects.
static createFormData(object: Object, form?: FormData, namespace?: string): FormData {
const formData = form || new FormData();
for (let property in object) {
if (!object.hasOwnProperty(property) || object[property] === undefined) {
continue;
}
const formKey = namespace ? `${namespace}[${property}]` : property;
if (object[property] instanceof Date) {
formData.append(formKey, object[property].toISOString());
} else if (typeof object[property] === 'object' && !(object[property] instanceof File)) {
this.createFormData(object[property], formData, formKey);
}
else if (typeof object[property] === 'number') {
let numberStr = object[property].toString().replace('.', ',');
formData.append(formKey, numberStr);
}
else {
formData.append(formKey, object[property]);
}
}
return formData;
}
}
In Component class:
export class HotelEditComponent implements OnInit {
formData = new FormData();
hotel: any;
...
ngOnInit() {
this.getOneHotel(this.route.snapshot.params['id']);
}
getOneHotel(id) {
this.http.get( this.apiUrl + '/api/hotel/' + id).subscribe(data => {
this.hotel = data;
});
}
postToServer() {
// or even can pass full `this.hotel` object
// this.helperService.createFormData(this.hotel)
this.formData = this.helperService.createFormData(this.hotel['hotelimages'])
this.service.post(this.formData);
}
...
}

It looks like you are trying to append a JSON array, since formData.append can only accept a string or blob, try the JSON.stringify() method to convert your array into a JSON string. (untested)
e.g. I think you can replace
this.appendImages(data['hotelimages']);
with
this.formData.append('hotelgallery', JSON.stringify(data['hotelimages']));

This is more of a design issue right now, rather then a tech problem. You are asking about posting FormData again and you want to fetch the images data again for that.
Now let's look at your current design.
User uploads 3 images of 4MB size each
On your edit page you downloads each of these images. Cost=12MB
On the edit page user deletes 2 images and adds 2 images. Cost=12MB
So final cost of updating 2 images of 8MB is 24MB. Which is a lot
Now before figuring out how to do FormData, figure out the right design for your app.
Consider the OLX site which allows you to post ads and later edit them. When you edit and remove a image, they call a API for removing the image
The ideal design in my opinion would be below
Submit all images in your create
For edit create a add and remove endpoint for the image
Submitting text data again on a edit form is ok, but submitting the same images data again on a edit form is never ok. Reconsider your design

Related

Send FileList in FormData in javascrirpt

I am trying to send a bunch of images using FormData but of course, I cannot send FileList and I was unsuccessful in figuring out a way to send these files. I have already tried to find answers on my own but most of them suggest appending each file.
for (let i = 0 ; i < images.length ; i++) {
formData.append("images[]", images[i]);
}
But it ends up with only the last file inside formData, for some reason previous files are being replaced by the next one in line.
I have also tried to convert FileList to an array, which works but I don't know how I could separate these files, right now every file is inside one key as a string.
0: "[{\"lastModified\":1606255989000,\"lastModifiedDate\":\"undefined\",\"name\":\"logo.png\",\"size\":54438,\"type\":\"image/png\"},{\"lastModified\":1606255979000,\"lastModifiedDate\":\"undefined\",\"name\":\"logo1.png\",\"size\":58023,\"type\":\"image/png\"},{\"lastModified\":1606252752000,\"lastModifiedDate\":\"undefined\",\"name\":\"logo2.png\",\"size\":28147,\"type\":\"image/png\"},{\"lastModified\":1606255121000,\"lastModifiedDate\":\"undefined\",\"name\":\"logo3.png\",\"size\":18260,\"type\":\"image/png\"}]"
I could just convert it to string and cut it to their own keys using } as and end of each entry. I don't want to do this, even with my little experience I know it's not a good way to go about it.
As of this moment, my javascript code looks like this.
File.prototype.toObject = function () {
return Object({
lastModified: parseInt(this.lastModified),
lastModifiedDate: String(this.lastModifiedDate),
name: String(this.name),
size: parseInt(this.size),
type: String(this.type)
})
}
FileList.prototype.toArray = function () {
return Array.from(this).map(function (file) {
return file.toObject()
})
}
let files = document.getElementById('files').files
let filesArray = files.toArray();
let formData = new FormData();
formData.append('images[]', JSON.stringify(filesArray));
I then send this data like this
fetch('<?=env('app.baseURL')?>/admin/gallery', {
method: 'POST',
processData: false,
headers: {
'X-Requested-With': 'XMLHttpRequest'
},
body: formData,
data: formData,
}).then(function (response) {...rest of the code...})
After sending this data, which is received without any problems I want to save these files, but I cannot without first separating them. I am using PHP for the back-end.
I don't have much experience with javascript so I might be missing something obvious, any help is appreciated.
In your for loop you could use dynamic name for your formData appends. For example:
formData.append(`image-${i}`, images[i])
Or in case you want to push your images to a single key value pair in your formData, like in your example, you should use the getAll() method to retrieve your images.
formData.getAll('images[]')
Here is the PHP code to go through the array containing the images :
<?php
if(isset($_FILES) && isset($_FILES['images'])){
$countfiles = count($_FILES['images']['name']);
for($i=0;$i<$countfiles;$i++){
$filename = $_FILES['images']['name'][$i];
$sql = "INSERT INTO myimages (filename) VALUES ('".$filename."')";
$db->query($sql);
move_uploaded_file($_FILES['images']['tmp_name'][$i],'upload/'.$filename);
}
}
?>

How to save the blob for media file?

I successfully make the wave data and get type and wave like this below.
then I use createObjectURL and it gives me the url http://localhost:3003/5025f231-f5d0-49f5-9851-600376de0065 but there is nothing.
How can I make the real file??
Any help appreciated...
console.log(type); //wave
console.log(data); //Blob {size: 6791616, type: "audio/wav"}
if (type == 'wav'){
//how can I save the .wav file from blob and give the parameter for user?
var dlUrl = URL.createObjectURL(data)
console.log(dlUrl); //it shows http://localhost:3003/5025f231-f5d0-49f5-9851-600376de0065, but there is no 5025f231-f5d0-49f5-9851-600376de0065 file.
}
I believe you have to add a blob: in front of the url:
console.log(type); //wave
console.log(data); //Blob {size: 6791616, type: "audio/wav"}
if (type == 'wav'){
//how can I save the .wav file from blob and give the parameter for user?
var dlUrl = URL.createObjectURL(data)
console.log('blob:' + dlUrl); //it shows http://localhost:3003/5025f231-f5d0-49f5-9851-600376de0065 and there is 5025f231-f5d0-49f5-9851-600376de0065 file.
}

Is it possible to store a file without using the pick method?

According to the filestack documentation you are supposed to call the pick method prior to store
Save files directly to your S3 bucket (or other storage). This works for both Blobs from a filepicker.pick call or for DOM File objects from an <input type="file"/>
Though the document states this, you can call store() without pick()
It looks like the pick function shows the interface to the user, which I do not want. I just want to upload a canvas image they've edited as a variable in my .blob, is this possible?
var canvasImage = canvas.toDataURL("image/png");
var blob = {
mainFile: canvasImage,
filename: this.file.name + '_edited',
isWriteable: true,
};
postFile(blob) {
var _this = this;
this.filepickerService.store(blob,
{
mimetype: "text/plain",
location: "S3",
path: "muhPath"
container: _this.appConfig.s3Bucket
},
function(new_blob){
console.log(JSON.stringify(new_blob));
}
);
}
Calling postFile only appears to work if I define a url instead of a blob. With a blob it throws:
Cannot store given input: " + input + ". Not a string, file input, DOM File, or FPFile object.
So, it looks like you are trying to pass the filepicker.store() method a canvas data url. This is not something the API can process.
It will take a raw base64 string (that you would also need to pass the base64decode parameter with), a standard file input, a DOM File , or the response from a previous Filestack transaction (fpFile object).
The canvas data url is probably something like this:
"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="
What the Filestack API expects would be:
"R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="
Here is an example that uses store to save a base64 string.
https://jsfiddle.net/amione/tq2zqtg1/
var data = "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";
Here is an example
filepicker.setKey("AtpK5JtiRgm3nWbe1vlI1z");
filepicker.store(
data, {
base64decode: true,
filename: 'image.png'
},
function(Blob) {
console.log("Store successful:", JSON.stringify(Blob));
addLink(Blob);
},
function(FPError) {
console.log(FPError.toString());
},
function(progress) {
console.log("Loading: " + progress + "%");
}
);
function addLink(data) {
$("#results")
.append(
'<li><a target="_blank" href="' +
data.url + '">' + data.filename + '</a></li>'
);
}
<script src="https://api.filestackapi.com/filestack.js"></script>
<ul id="results">
</ul>

Struts2 Action Form Data Maximum Size for Image Upload using Base64

I have a Struts2 action that receives a string containing an image in Base64 and another string for the image name.
Everything works well for small sized images. But when I try to send a larger image, the Base64 and the image name strings are set to null in the action implementation.
In search for a solution I found that the default maximum size for the file upload is 2 MB. This limit can be increased with the following properties:
<constant name="struts.multipart.maxSize" value="104857600" />
<param name="maximumSize">52428800</param>
<param name="fileUpload.maximumSize">52428800</param>
However this is not working. Probably this implementation is not a file upload but a two string POST request.
Is there a way I can increase the size of the post request? Or the problem is something else?
public class GalleryAction extends BaseAction {
private String imageBase64;
private String imageName;
...
public final String uploadOperation() throws Exception {
if (this.imageBase64 == null || this.imageBase64.length() == 0
|| this.imageName == null || this.imageName.length() == 0) {
throw new Exception("Invalid argument");
}
byte[] decodedBytes = Base64Decoder.decode2bytes(this.imageBase64);
InputStream is = new ByteArrayInputStream(decodedBytes);
Graphics graphics = MGraphics.insertImageToDataBase(this.imageName, is);
// Issue server to sync image.
RestUtils.syncImage(graphics.getId());
JSONObject response = new JSONObject();
response.put("statusCode", "0");
jsonString = response.toString();
return JSON_RESPONSE;
}
...
}
EDIT:
I forgot to publish the code for the image upload.
Gallery.prototype.upload = function(base64, imageName) {
var galleryObject = this;
galleryObject.loadingCallback(true);
$.post(this.urlBase + "/upload", {
"imageBase64" : base64.match(/,(.*)$/)[1],
"imageName" : imageName
}, function(data) {
galleryObject.handlerErrorMessageCallback();
galleryObject.loadingCallback(false);
galleryObject.refreshImageGalleryCallback();
}, "json")
.fail(function() {
galleryObject.handlerErrorMessageCallback("error.upload.image");
galleryObject.loadingCallback(false);
});
}
The HTTP protocol specifications don't set a limit to the size of a POST message. However, your application server does it (mainly to prevent DDoS attacks).
Usually this threshold is 10 MegaBytes, and it is the one you are hitting. You should then be able to customize this setting according to your AS specs.
That said, this is not encouraged, and could lead to security vulnerabilities.
The best thing would be to:
use multipart/form-data over application/x-www-form-urlencoded;
use File instead of String since what you're uploading are files, and not strings.
I changed the upload method to Form data.
Gallery.prototype.upload = function(base64, imageName) {
var galleryObject = this;
galleryObject.loadingCallback(true);
var request = new FormData();
request.append("imageBase64", base64.match(/,(.*)$/)[1]);
request.append("imageName", imageName);
$.ajax({url:this.urlBase + "/upload",
data: request,
type: "POST",
processData: false,
contentType: false,
success: function(result)
{
galleryObject.handlerErrorMessageCallback();
galleryObject.loadingCallback(false);
galleryObject.refreshImageGalleryCallback();
}
}).fail(function() {
galleryObject.handlerErrorMessageCallback("error.upload.image");
galleryObject.loadingCallback(false);
});
}
Using this post method the following property on strus.xml must exists
<constant name="struts.multipart.maxSize" value="104857600" />

Publishing photo as multipart/form-data to Facebook using Javascript graph API v2.5

Facebook's Graph API (v2.5) User Photo Edge says that there are two separate ways of publishing photos to Facebook:
1: Attach the photo as multipart/form-data. The name of the object doesn't matter, but historically people have used source as the parameter name for the photo.How this works depends on the SDK you happen to be using to do the post.
2: Use a photo that is already on the internet by publishing using the url parameter:
FB.api(
"/me/photos",
"POST",
{
"url": "{image-url}"
},
function (response) {
if (response && !response.error) {
/* handle the result */
}
}
);
I need to use the first method (multipart) as I have got the base64 image data from canvas.
This seems to be confusing as I don't find the documentation very informative. I understand that the urlData of image is to be encoded in some format in the multipart data along with other parameters. I fail to find any working sample code/proper explanation on how to do this using Javascript SDK & graph api v2.5; even after an exhaustive search on stackoverflow. I have seen a various partially answered/unanswered questions regarding this on stackoverflow...But I still fail to get it work.
Please help. Thanks !
Similar Questions
Facebook Javascript Form Data Photo Upload: requires upload file error
Javascript: Upload image from Canvas to FB via Graph API
Upload Base64 Image Facebook Graph API - Not clear if Javascript Api has been here
[Edit] - Code I have already tried.
var ctx = document.getElementById('canvas2');
urldata=ctx.toDataURL("image/png");
FB.api('/photos', 'POST', {
message: 'testing Graph API',
access_token: accessToken,
url: urldata,
no_story:true
}, function (response) {
if (!response || response.error) {
console.log('Error occured:' + response.error.message);
} else {
alert('Post ID: ' + response.id);
}
}
);
Response -"
Error occured:(#324) Missing or invalid image file "
I was not able to use the JS SDK with this, but it works with a simple AJAX request (with the Fetch API, axios or something else).
First, turn the Canvas Image into a Blob with the following function:
const dataURItoBlob = (dataURI) => {
let byteString = atob(dataURI.split(',')[1]);
let ab = new ArrayBuffer(byteString.length);
let ia = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {
type: 'image/jpeg'
});
}
After that, you can use the blog with FormData:
formData.append('source', blob);
Source: http://www.devils-heaven.com/facebook-javascript-sdk-photo-upload-from-canvas/

Categories