Axios post request with formData - reactjs

I want to make a form with multiple input (two text and one image).
Furthermore, I'm using react, axios, formik and I submit my data to strapi.
With only one text and one file, it works fine, but when I try to add a new append, I've got the error
When using multipart/form-data you need to provide your data in a JSON 'data' field.
const onSubmit = async (event) => {
const data = new FormData()
//This works
data.append('data', JSON.stringify({title:event.title}))
data.append('files.cover', file)
//This doesnt
data.append('title', JSON.stringify({title:event.title}))
data.append('description', JSON.stringify({description:event.description}))
data.append('files.cover', file)
try{
const response = await axios.post('http://localhost:1337/foodtrucks', data,
{
headers: userToken && { Authorization: `Bearer ${userToken}` }
},
)
// const data = await response.json()
console.log("response", response)
} catch(err){
// setError(err.response.data.message[0].messages[0].message)
setError("error")
console.log(err)
}
}
I tried to add headers, to use form-data, etc. Nothing works.

I think axios is meant for calling APIs - it may not be easy (or possible to send form data).
If you're running in the Browser, you may want to use plain XMLHttpRequest. I came across this article, which defines the submitForm function. It has helped me a lot on many projects.

Related

How to send multipart form data with React (Next) / Redux / Saga?

I am sending img file with usual React Saga and Next.js. I never worked with sending multipart form data so I don't know how to do it. I usually send image in a body in base64 format.
This is UI part:
const onUploadLogo = (e) => {
var img = e.target.files[0]
let formData = new FormData()
formData.append("file", img)
console.log('image check => ', img)
console.log('formData check => ', formData)
updateLogoFunc({ // this is the API call
formData // body
})
}
<label className="custom-file-upload">
<input type="file" onChange={onUploadLogo} accept="image/*" />
Attach
</label>
In 'image check => ' I see that my image is uploaded, I see the file, however 'formData check => ' gives me undefined. Just fyi, saga call of API works just fine, no problem with that. If you need the code of saga:
export function* updateLogoSaga(action) {
try {
yield put(setLoader(true))
const response = yield ApiStore.garage.post(`UpdateLogo`, action.values)
yield put(setLoader(false))
} catch (error) {
yield put(setLoader(false))
}
}
My problem is I do not know how to send this damn image as multipart form data by POST call.
var img = e.target.files[0]
const formData = new FormData();
formData.append("file", img);
So far you got the file, but it is important how you are going to send it to the server.
If you need to send a buffer
const buffer = await file.arrayBuffer();
or as bytes
// each entry of array should contain 8 bits
const bytes = new Uint8Array(buffer);
So now your data is ready, you have to send it to the server. But it is not clear how you are going to send it to the server. are you going to send the image separete from other form inputs (In some case you might verify the image so you handle it separately). If you are going to send the image with form, together with other inputs inside a submitHandler it is better you write the above code inside onChange, set the file as state value and inside submitHandler you dispatch the input values. So far is the process of handling the image.
In saga, you have to create an action with type and your saga store would be listening to that type and once it receives that type, it will call the updateLogoSaga and your updateLogoSaga is seems correct.

React fetch local json file for testing does not work

I'm trying to fetch a .json file from local, and
I get response 200 but with a body response of HTML: "You need to enable JavaScript to run this app."
I have javascript enabled of course.
I don't want to import the file to simulate the real fetch.
How does local fetch work in react? How do I know if the fetch route is right? It doesn't give any useful error hint.
useEffect(() => {
const getData = async () => {
const dataFromLocal = await fetchData();
console.log('dataFromLocal', dataFromLocal);
}
getData();
}, [])
const fetchData = async () => {
const response = await fetch('data.json');
const data = await response.json();
return data;
}
I found how it works:
const response = await fetch('data.json',
{headers:
{'Content-Type': 'application/json','Accept': 'application/json'}
});
just add this headers object to the fetch method and it works
There are only two possibilities based on the code you've shown:
Your server is responding with the contents of an HTML resource (likely index.html) as the response to the request for data.json, or
data.json looks like this, the JSON string you provided:
"You need to enable JavaScript to run this app."
Is data.json in your project's ./public folder?

Why am I getting empty array in fetch request to MongoDB from ReactJS?

I am trying to fetch all the articles from a document in MongoDB in React. It is perfectly working in Backend with NodeJS when I tested with Postman. But in Frontend , React, I am getting empty array. How to solve this.
Server.js (Backend)
app.get('/api/articles', async (req, res)=>{
const client = await MongoClient.connect('mongodb://localhost:27017', {useNewUrlParser:true, useUnifiedTopology:true})
const db = client.db('my-blog')
const articleInfo= await db.collection('articles').find({}).toArray(function(err, result){
if (err) console.log(err)
res.status(200).send(result)
client.close()
})
})
articlePage.js (FrontEnd)
componentDidMount(){
const requestOptions = {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
};
const fetchdata = fetch('/api/articles/').then(res=>res.json())
.then(data=>this.setState({articles:data}))
console.log(this.state.articles)
}
Api address is set up in package.json with proxy:http://localhost:8000
How to get the documents data from MongoDB in React?
Firstly, check if you the API call went through to the server from your React app. If it has, then check for the response code in the network. In your case, 200 is where you get the desired result from the API. If you are not getting the desired result, then check your collection and document names and also arguments your are passing in the query.
As setState is not synchronized, you have to access it in the callback.
this.setState({ articles: data }, () => {
console.log(this.state.articles)
})

Api fetch responses Blob structure in React Native app

I'm consuming a web api from my React Native Android project. After updating my react-native version to 0.60.3 my response data is not returning JSON, it returns Blob data structure.
This is what I get from then(res=>{...})
Please look at the image
Screen-Shot-2019-07-18-at-17-25-10.png
The _bodyInit object was returning JSON. But now it returns Blob that I can not reach from Js code.
I tried using functions res.json(), res.text()
They worked! But this time I just got data inside the _bodyInit. I can not reach other parameters like ok, header etc.
This is what I've tried. Like I said, it works. But it returns response with just my data, not other parameters like ok, headers etc.
.then((res) => res.json())
.then((res) => {
if (res.ok) {
// No 'ok' element anymore after .json()
}
});
In the 'devtools' if I click the '_bodyInit' object. Simulator gives error below.
Screen-Shot-2019-07-18-at-17-32-49.png
Do you have any idea to solve this issue?
Thanks in advance!
ok property is with response before you call json method on it. If your response contains json, call json to serialize body as json, if response contains blob, call .blob to serialize body as blob. See more proerties of Response here.
.then((res) => {
console.log("response.ok", res.ok)
// print headers,
console.log("headers", res.headers.forEach(item=>console.log(item)))
// if response if json, call res.json
return res.json()
})
.then((res) => {
// here you will only get json data, not other properties.
console.log("json data is ", res)
});
SOLVED
I found two way to solve this problem.
Using .then() after using .json()
.then((res) => {
if (res.ok) {
res.json().then(res=>{
console.log(res)
})
} else console.log("not ok")
});
Using async and await
.then(async res => {
if(res.ok) {
const response = await res.json()
console.log(response)
} else console.log("not ok")
})
That would be great to see other solutions from you. Thanks.

How to fetch data from Microsoft Custom Vision API using ReactJS

I need some help regarding the use of Custom Vision. I built an image classifier in order to detect car damages.
So what I am trying to do: when I try to input an image and click the submit button, I want to be able to call the Custom Vision API and get the results in order to be able to analyze them later using ReactJS
I tried using AXIOS and the componentDidMount() method, but I can't seem to get a hold of them.
componentDidMount(){
axios.get('url: "https://southcentralus.api.cognitive.microsoft.com/customvision/v3.0/Prediction/...",
// Request headers {
prediction: ("Prediction-Key","xxx");
content: ("Content-Type","xxx");
},
type: "POST",
// Request body
data: imgContent,
processData: false')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.log(error);
});
}
your request type is post and you are using axios.get()
Check your code, // Request headers {
prediction: ("Prediction-Key","xxx");
content: ("Content-Type","xxx");
},
The first bracket seems to be commented out so this may be a potential problem.
You should use async/await with the componentDidMount method.
An example
async componentDidMount() {
const response = await fetch(`https://api.coinmarketcap.com/v1/ticker/?limit=10`);
const json = await response.json();
this.setState({ data: json });
}

Resources