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

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.

Related

Axios seemingly manipulates passed data

My current NuxtJS Application contains the following code:
// Create a new Canvas-Object on a Whiteboard
async createCanvasObject({ state }, canvasObject) {
if (!state.id) {
console.error(' Canvas ID is not defined!');
return;
}
console.log(canvasObject);
console.log(canvasObject.mtiID);
await this.$axios
.$post(`/whiteboard/${state.id}/canvas/object`, {
object: canvasObject,
})
.then((res) => console.log(res));
},
What should this code do?
It should send a passed object canvasObject via POST-Request to my backend, without modifying it.
The canvasObject itself is a JSON-Object, which describes an Object on a Canvas.
The logging directly before the Axios-Call yields something like this:
As you can see, there is a lot of stuff defined, and espacially the attribute mtiID.
Now the Problem:
If we look at the request, we can see, that a lot of stuff got stripped away from my JSON, including the mtiID. I have no idea why. The only 'Middleware', that is currently applied to Axios just logs every request to the console, without modifying it.

Data VS Async Data in Nuxt

Im using vue.js with nuxt.js, I'm just still confused as when to use Data VS Async Data. Why would I need to use Async data when I just have data that just displays on the page?
I have a data object of FAQ's and just want to display the data without doing anything with it. What are the benefits of using the asyncData? Or what are the cases or best use of them?
Should I display list data such as this as async by default if using data such as this inside of my component?
Data
data:() => ({
faqs:[
{"title":"faq1"},
{"title":"faq2"},
{"title":"faq3"},
]
}),
asyncData
asyncData(context) {
return new Promise((resolve, reject) => {
resolve({
colocationFaqs:[
{"title":"faq1"},
{"title":"faq2"},
{"title":"faq3"},
]
});
})
.then(data => {
return data
})
.catch(e => {
context.error(e);
});
},
asyncData happes on the serer-side. You cant access browser things like localStorage or fetch() for example but on the ther hand you can access server-side things.
So why should you use asyncData instead of vue cycles like created?
The benefit to use asyncData is SEO and speed. There is this special context argument. It contains things like your store with context.store. Its special because asyncData happens on server-side but the store is on the client side usually. That means you can get some data and then populate your store with it and somewhere else you display it. The benefit of this is that its all server-side and that increase your SEO so for example the google crawler doesnt see a blank page
why would I need to pre render it when it is going to be displayed
anyway
Yes for us it doesnt matter if i send 1 File to the client and it renders all data like in SPA's or if its pre-rendered. But it doesnt matter for the google crawler. If you use SPA mode the crawler just sees a blank page. You can discoverd it too. Go to any SPA website and click right-click and inspect you will see thats there only 1 Div tag and few <script> tags. (Dont press F12 and inspect like this thats not what i mean).

React, Redux, Filepond

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/

How to get data from multiple url's in Reactjs?

I want to get json data from multiple url's and display it on frontend.
Following are the url's:
1) localhost:3000/api/getdata1
2) localhost:3000/api/getdata2
3) localhost:3000/api/getdata3
Instead of using .fetch() on each of the url's like below:
.fetch('localhost:3000/api/getdata1')
.fetch('localhost:3000/api/getdata2')
.fetch('localhost:3000/api/getdata3')
Can this be done in more efficent way in ReactJs ?
I was trying:
const dataurls = [
'localhost:3000/api/getdata1',
'localhost:3000/api/getdata2',
'localhost:3000/api/getdata3'
];
const promisedurl = dataurls.map(httpGet);
Promise.all(promisedurls)
.then(data=> {
for (const d of data) {
console.log(d);
}
})
.catch(reason => {
// Receives first rejection among the Promises
});
Please suggest which one should be used or is there any efficient way to do get data from multiple url's.
ReactJS is a View layer library. It has nothing to do with how you aquire any data from server.
Even state libraries, like Redux and Reflux do not implement any method of fetching data. In most cases you do that in your custom app code. Sometimes using extra libraries (e.g. Redux middlewares).
So, yes: your Promise.all(<several https requests here>) is the most natural way to achieve that.

Trying to hit an API with JSON data in REACT

I have just started learning to code in ReactJS and have come to the part where I need to hit an API to get back JSON data.
I am running this on a node server on my local which tries to build it each time I make a change - this helps because it shows me where my errors are. Unfortunately it doesn't mean I know why I am getting an error.
This is my code so far:
import React from 'react';
import './App.css';
var GetUnassignedClients = React.createClass({
unassignedClients: function () {
return $.getJSON('http://localhost/backoffice/?action=unassignedClients.getUnassingedClients')
.then((data) => {
this.setState({resultMe: data.results});
});
},
render: function() {
return (
<div>this.state.resultMe</div>
);
}
});
module.exports = GetUnassignedClients;
I will re-paste the bit that seems to be throwing the error:
return $.getJSON('http://localhost/backoffice/?action=unassignedClients.getUnassingedClients')
.then((data) => {
this.setState({resultMe: data.results});
});
The error seems to be pointing at the $ - when I wrap this all in {} then it points to the full stop (.).
Not sure if I am doing something wrong or missing something.
The $in the $.getJSON is referring to jQuery. Do you have it included in your page? Javascript is trying to parse the dollar sign and can't find it. Other possible solution is to use a separate http library (if you don't need jQuery), such as axiois or fetch for example.
Im not sure, but I thought you would hit in this way
fetch(`http://localhost:8088/api/this/is/an/api/call`)
.then(result=> {
this.setState({items:result.json()});
});
Okay turns out I was trying to use $.getJSON which is JQuery - due to building this on my local using a node server JQuery wasn't included on my local development before the production code was built.
So instead I looked into using fetch that seems to be the go to when coding in react.
I also moved this section into a componentDidMount function so the app would be loaded and then the API call would be made - not that I have a lot of data to load but it's good practice for when you do.
My working code for this section:
componentDidMount () {
fetch("http://localhost/dashboard/?action=unassignedUsers.getUnassingedUsers", {
credentials: 'same-origin'
})
.then(response => response.json())
.then(json => this.setState({data: json}));
}
I also came across a couple issues using fetch - if you need a session available to access said data then you need to specifically pass through the credentials or the API call will re-direct to the login page. At first I saw a status 200 but no data - as it successfully re-directed to the login page, but obviously there was no JSON to access here.

Categories

Resources