React, Redux, Filepond - javascript

My question... how do I upload files using FilePond but onclick, not automatically like it does out of the box? Also, since I need to take a number of other actions with theses images (like display them for review prior to upload) and since I need to add other data to the FormData that gets sent (plus dispatch actions to Redux).
Normally I would create a FormObject append the files and other values to it before POSTing it to some endpoint (with any custom headers needed). However when I inspected the FilePond instance it seems like the only thing I have access to is a blob... not the actual files. Is this accurate? Do I need to follow some special FilePond specific technique to get file upload to work?
FilePond's docs have a custom config value called "server" that appears to have access to an actual file in the more advanced examples so is this the way it must be done? I can't just grab the files (from somewhere that I do not currently see on the FilePond instance) and append them to an object for use in my normal "service"?
Any tips are appreciated. In a React app I want to upload a variable number of files onclick after appending other form data and setting headers (using Axios, ideally) and POST these files to an API.
Example from their docs uses a prop like:
server="/api"
I want something like (fake code):
server={submitImages} <-- this should only happen onclick of some button
where:
submitImages = (fieldName, file) => {
const formData = new FormData()
formData.append(fieldName, file, file.name)
formData.append('foo', this.props.foo)
const docuploadresult = this.props.uploadDocs(formData) <-- a service that lives elsewhere and actually does the POST
docuploadresult.then(result => {
// success
}, error => {
// error
})
}
and my problems are that I don't see why this needs to happen in some special config object like server, don't see how to make this happen onclick, don't see an actual file anywhere.
I may be overthinking this?

FilePond offers the server property so it can handle the uploads for your. But this is not required, you can use getFiles to easily request all file items (and File objects) in FilePond and upload them yourself.
Add your own submit button to the form and use submitImages below to submit the files.
submitImages = (fieldName) => {
const formData = new FormData();
this.filepondRef.getFiles()
.map(fileItem => fileItem.file)
.forEach(file => {
formData.append(fieldName, file, file.name);
});
// upload here
}
If you want to show image previews you can add the image preview plugin.
https://pqina.nl/filepond/docs/patterns/plugins/image-preview/

Related

How to send file from VueJS to API/ExpressJS using axios

Firstly, sorry if my english is bad, i'm not native.
My problem is simple : i already succeded at post some form data from VueJS to ExpressJS API using axios just like that:
axios.post('urlOfMyAPI', this.body).then(response => this.rep = response.data);
The "this.body" thing is an object called body and inside this object, i map all my inputs, like that by example:
<v-textarea v-model='body.text'></v-textarea>
It work well, expressJS can take the data and do the job but when i try to do it with a "v-file-input", all the data inputs go to the API correctly, except the file. When i'm trying to console.log in my API (see the screen under) a random data from input in my API, the data is rendered in my console but the data file is rendered as "undefined".
Have to say one last thing : When i do "console.log(this.body)" in vueJS before the axios post, my file is in the body like expected, so the problem is with axios. I tried to find something on internet but just got some things with a "FormData" object i don't understand and tried to use without success.
My API Code btw, just for example :
exports.Create = (req,res) => {
console.log(req.body.text);
console.log(req.body.file.name);
}
Thanks you if you help me
You have to use formData when submitting files to axios, otherwise, your files won't be available on server-side.
This is a simple method that performs an upload of a file. Please note: if you want to send additional data within your request, you have to add as many formData.append() as you have properties.
uploadAvatar () {
const formData = new FormData()
formData.append('avatar', this.file)
formData.append('other_field', this.otherField)
axios.post('/avatars/upload', formData)
.then((response) => {
console.log(response.data)
})
.catch((e) => {
console.log(e)
})
}
From my experience, if you have a huge form and you want to avoid many formData.append(), the best option is to handle your uploads separately.

How can I save a string to a textfile in Cloud Storage, in an angular app?

Here is my problem:
I'm writing an angular app, I use App Engine and Google Cloud Storage as the backend (JAVA 8). Now I have text, and I want to save it to my database. Using cloud storage I need this text to be saved as a file. One manner to do that would be to convert my string into a file Object and send it to server via a multipart request.
How can I do that?
Here is my code so far (the aim of that code is to send a photo plus a text description):
uploadAlbum(index:number){
const formData = new FormData();
//`myPhoto` is a file created with the <input type="file"> tag
formData.append('file', myPhoto, '/gcs/my-bucket/' + index +'/cover/cover.jpg');
//here is my problem here `description` is not a file
formData.append('description', description, '/gcs/my-bucket/' + index +'/cover/cover.txt');
this.http.post('/api/photos',formData).subscribe(
(data: any) => {
response = data;
},
err => {
console.log(err)
}
);
}
As description variable is a string, I get the following error on my console:
ERROR TypeError: "Argument 2 of FormData.append is not an object."
NOTE:
Even if that can seem out of subject I added tags for the backend server on my post as I'm open to solve this issue creating a file on the backend also.
description is not a file because probably it's not present on the client side.
formData.append() is used to append the files with formData to upload them with form data.
Well you can not save a file to server using javascript.
see it has already been answerd here
(Saving a text file on server using JavaScript)

Fine-Uploader Replace File but keep UUID

Does Fine-Uploader have the concept of replacing an existing file, but keeping the same UUID?
My uploaders are restricted to one file only. When clicking upload file again (after a file has already been successfully uploaded) results in a new UUID created for the new file. I'd like to keep the same UUID since it may already be cross linked to other data points in our back end.
Reusing a UUID for multiple files defeats the entire purpose of a UUID. So this is not supported.
I had the exact same use case and did not find a direct solution. The easiest solution for me was to handle the onSubmit event and change the UUID to a value that you create in your back end.
var sameUuid = qq.getUniqueId();
var uploader = new qq.FineUploader({
callbacks: {
onSubmit: function (id, fileName) {
this.setUuid(id, sameUuid);
}
}
});
You could also generate a second UUID that does not change and send it along as a parameter or as a custom header.

Upload image to firebase and set a link in database

I know how to add data to the firebase database, I know how to upload image to the firebase storage. I am doing this in javascript.
I am not able to figure out how to link the image to my database object.
My database object is something like this
{
name:'alex',
age:23,
profession:'superhero'
image:*what to put here ???*
}
One idea is to use the object reference that is created and store the image using the same reference.
Any tutorial or ideas appreciated.
We often recommend storing the gs://bucket/path/to/object reference, otherwise store the https://... URL.
See Zero to App and it's associated source code (here we use the https://... version) for a practical example.
var storageRef = firebase.storage().ref('some/storage/bucket');
var saveDataRef = firebase.database().ref('users/');
var uploadTask = storageRef.put(file);
uploadTask.on('state_changed', uploadTick, (err)=> {
console.log('Upload error:', err);
}, ()=> {
saveDataRef.update({
name:'alex',
age:23,
profession:'superhero'
image:uploadTask.snapshot.downloadURL
});
});
This upload function sits inside a ES6 class and is passed a callback (uploadTick) for the .on('state_changed') from the calling component. That way you can pass back upload status and display that in the UI.
uploadTick(snap){
console.log("update ticked", snap)
this.setState({
bytesTransferred:snap.bytesTransferred,
totalBytes:snap.totalBytes
})
}
The file to upload is passed to this upload function, but I am just using a react form upload to get the file and doing a little processing on it, your approach may vary.

Change Jquery file upload url dynamically

I am using jQuery File Upload in my project. I am having problem changing the URL dynamically i.e. I want to change the upload folder dynamically. I have seen some posts e.g.
jQuery File Upload: how to change the upload url dynamically
https://github.com/blueimp/jQuery-File-Upload/issues/2640
But these both tell to change "data.url" but data.url changes the folder where PHP files are uploaded.
I am able to solve this using sessions by changing these lines in upload handler.php from
'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/files/',
'upload_url' => $this->get_full_url().'/files/',
to
'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/'.$_SESSION['cid'].'/',
'upload_url' => $this->get_full_url().'/'.$_SESSION['cid'].'/',
But what happens if user has two different pages opened at a same time then it will upload all to the same folder because session variable wont be updated. Is there any possible solution to this using Javascript? so I wont need to worry about that. Any help will be much appreciated.
Thanks
The only solution is to solve it using sessions by changing these lines in upload handler.php from
'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/files/',
'upload_url' => $this->get_full_url().'/files/',
to
'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/'.$_SESSION['cid'].'/',
'upload_url' => $this->get_full_url().'/'.$_SESSION['cid'].'/',
This may not be the EXACT answer you might be looking for but following the steps can get you to your answer.
I had this kind of similar problem. I solved it by passing an extra variable to the script and change the upload_dir variable in php.
Your default index.php filw should look like this.
error_reporting(E_ALL | E_STRICT);
require('UploadHandler.php');
$upload_handler = new UploadHandler();
I modified it to listen for extra variable that I pass from JS. Look at the comments to see what is happening. Essentially what is happening is it makes sure that the extra variable called fuPath is received when call is made to this file (from javascript) and if not, do not upload the file. If the path is received then use it to get final destination based on web root directory.
error_reporting(E_ALL ^ (E_NOTICE | E_WARNING));
require('UploadHandler.php');
$urlHolder = NULL;
// This option will be used while uploading the file.
// The path will come as POST request.
if( isset($_POST['fuPath']) ) {
// perform validations to make sure the path is as you intend it to be
$urlHolder = filter_var($_POST['fuPath'], FILTER_SANITIZE_URL);
}
// This option will be used when deleting a file.
// The file details will come from GET request so have to be careful
else if( isset($_GET['fuPath']) ){
// perform validations to make sure the path is as you intend it to be
$urlHolder = filter_var($_GET['fuPath'], FILTER_SANITIZE_URL);
}
else{
exit;
}
$options = array(
'upload_dir'=> $_SERVER['DOCUMENT_ROOT'] .'/' .$urlHolder,
// 'upload_url'=>'server/php/dummyXXXX', // This option will not have any effect because thumbnail creation is disabled
'image_versions' => array(), // This option will disable creating thumbnail images and will not create that extra folder.
// However, due to this, the images preview will not be displayed after upload
);
if($urlHolder){
$upload_handler = new UploadHandler($options , true , null);
}
Now on JS side I have made the following changes.
var fullUpldPath = "";
// when file upload form is initialised then along with other options I also set the file upload path "fuPath".
// default will be empty string, so we can validate in php code.
$(localFormNames.fileForm).fileupload({
formData: {fuPath: fullUpldPath}
});
Now back to HTML. I have created a dummy button (lets call #uploadFiles) which user clicks to upload images. This is required because I want to manipulate this fuPath variable in between the time when user clicks to upload and upload starts. The plugin's upload button (lets call it #pluginButton) is hidden.
So when user click #uploadFiles, I change my file upload path as required. Set the modified variable and then click the actual plugin's upload button.
// ending / is mandatory.
fullUpldPath = "assets/uploadedImages" + $("#imagename").val() + "/";
$(localFormNames.fileForm).fileupload({
formData: {fuPath: fullUpldPath}
});
// Now manually trigger the file upload
$("#pluginButton").click();
I use user directories. See:
https://github.com/blueimp/jQuery-File-Upload/wiki/PHP-user-directories
index.php
require('UploadHandler.php');
class CustomUploadHandler extends UploadHandler {
protected function get_user_id() {
#session_start();
return $_SESSION['mySubDynamicDir'];
}
}
$upload_handler = new CustomUploadHandler(array(
'user_dirs' => true
));

Categories

Resources