How do I make a PUT request with axios? - reactjs

I'm trying to update a field on my MongoDB database with Axios PUT method in React JS. I'm also using react form hook.
const onSubmit = async itemData => {
console.log(itemData);
const url = `http://localhost:5000/items/${id}`
const { data } = await axios.put(url, {
productQTY: itemData.productQTY,
headers: {
authorization: `Bearer ${localStorage.getItem('accessKey')}`
}
})
so I can access itemData.productQTY from itemData. There is also a field in the Database named productQTY, so how do I update the field?

const onSubmit = async itemData => {
console.log(itemData);
const url = `http://localhost:5000/items/${id}`
const { data } = await axios.put(url,
{ productQTY: itemData.productQTY },
{
headers:
{
authorization: `Bearer ${localStorage.getItem('accessKey')}`
}
}
})
u can try it, with data and header in 2 params of put request.

Related

ReactJS: POST 400 (Bad Request) using Axios

I am using axios to hit an API to upload a .apk file onto a 3rd party app which is running locally on my computer. Using the API on Postman is giving the desired result but while integrating it with my React app I am getting POST http://localhost:8000/api/v1/upload 400 (Bad Request) error.
I have the following with structure:
src/httpRequest.js
import axios from "axios";
export default axios.create({
baseURL: "http://localhost:8000",
headers: {
"Content-type": "application/json",
Authorization: <API_KEY>
}
});
src/services/Upload.js
import http from "../httpRequest";
const upload = (file, onUploadProgress) => {
const formData = new FormData();
formData.append("file", file);
return http.post("/upload", formData, {
headers: {
"Content-Type": "multipart/form-data",
Authorization:
<API_KEY>
},
onUploadProgress,
});
};
export default {
upload,
};
src/components/ApkUpload.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const ApkUpload = () => {
const [selectedFiles, setSelectedFiles] = useState(undefined);
// eslint-disable-next-line no-unused-vars
const [currentFile, setCurrentFile] = useState(undefined);
const [progress, setProgress] = useState(0);
const [message, setMessage] = useState('');
const [fileDetails, setFileDetails] = useState([]);
const handleUpload = async () => {
const data = new FormData();
data.append('file', selectedFiles);
try {
const res = await axios.post('http://localhost:8000/api/v1/upload', data, {
headers: {
'Content-Type': 'multipart/form-data',
Authorization: <API_KEY>,
},
onUploadProgress: (progressEvent) => {
setProgress(parseInt(Math.round((progressEvent.loaded * 100) / progressEvent.total), 10));
},
});
} catch (err) {
if (err.response.status === 500) {
setMessage('There was a problem with the server');
} else {
setMessage(err.response.data.message);
}
}
};
const handleChange = (e) => {
setSelectedFiles(e.target.files);
setCurrentFile(e.target.files[0]);
};
useEffect(() => {
axios.get("http://localhost:8000/api/v1/scans", {
headers: {
Authorization:
<API_KEY>,
},
}).then(res => {
setFileDetails(res.data.content);
});
},[]);
return (
<div className="container">
// simple button calling above methods
</div>
);
};
export default ApkUpload;
I am using MobSF as my third party app and for upload they require multipart/form-data.
While using postman I was able to get the desired result but I'm not able to do so with my frontend. Any help regarding this issue will be highly appreciated!
const data = new FormData();
data.append('file', selectedFiles[0]);
Inside your handleUpload function selectedFiles state is of type FileList but it should be File.
If you are handling single file then you can use:
data.append('file', selectedFiles[0]);
For multiple files you can do:
for(let i=0;i<selectedFiles.length;++i){
data.append('file',selectedFiles[i])
}

Not able to implement data from one api used to get data from another

I am making a meme sharing app. In that app there are total 2 apis of getting memes.
One for memes by all the users another is only for individual user.
In second api I am able to get the data as the user id is from 3rd api.
from here i get the id of each individual.
function UserProfile({memeid}) {
const token = localStorage.getItem("token");
const [response, setResponse] = useState({});
const [id, setId] = useState('')
const userData = async() => {
await axios
.get("http://localhost:8081/userInfo/me", {
headers: { Authorization: `Bearer ${token}` },
Accept: "application/json",
"Content-Type": "application/json",
})
.then((res) => {
setResponse(res.data)
setId(res.data.id)
memeid = id
})
.catch((err)=>{
console.log(err)
})
}
console.log(id)
useEffect(()=>{
userData()
},[])
Now I want this to be used in in another api. for that is have written this code.
function MemeById({id}) {
const [response, setResponse] = useState([])
const token = localStorage.getItem("token");
// const id = "632a119672ba0e4324b18c7d"
const memes = async () => {
await axios
.get("http://localhost:8081/memes/" + id, {
headers: { Authorization: `Bearer ${token}` },
Accept: "application/json",
"Content-Type": "application/json",
})
.then((res) => {
const data = res.data;
setResponse(res.data)
console.log(data);
})
.catch((err) => {
alert(err);
console.log(err);
});
};
useEffect(()=>{
memes()
},[])
I am calling these two at User
function User() {
let id;
return (
<div>
<UserProfile memeid={id}/>
<MemeById id = {id} />
</div>
)
}
I am getting the error for this.
How to solve this error
You're making a big mistake. I think you should learn more about state and props in react.
Problem :
In your User component, you're creating a variable and passing that variable into two other component. You're trying to update the value of props from UserProfile and expecting that updated value in MemeById which is not going to work.
Solution :
function User() {
const [memeId, setMemeId] = useState(null);
return (
<div>
<UserProfile updateId={(newId) => setMemeId(newId)}/>
<MemeById memeId = {memeId} />
</div>
)
}
And in your UserProfile component
function UserProfile({updateId}) {
...
const userData = async() => {
...
// memeid = id
updateId(res.data.id)
...
}
In you MemeById component:
function MemeById({memeId}) {
...
// use memeId here
...
}

How to create a global 401 unauthroized handler using React + ReactQuery + Axios stack?

So I architected frontend in the way which encapsulates every API operation tied to a single resource inside custom hook like this:
export default function useSubjects() {
const queryClient: QueryClient = useQueryClient();
const token: string | null = useStore((state) => state.user.token);
const { yearCourseId } = useParams<{ yearCourseId: string }>();
const getSubjects = async () => {
const response = await axios.get(`yearCourses/${yearCourseId}/subjects`, {
headers: { Authorization: `Bearer ${token}` },
});
return response.data;
};
const postSubject = async (subject: SubjectType) => {
const response = await axios.post(`yearCourses/${yearCourseId}/subjects`, subject, {
headers: { Authorization: `Bearer ${token}` },
});
return response.data;
};
const query = useQuery(SUBJECTS_QUERY_KEY, getSubjects);
const postMutation = useMutation(postSubject, {
onSuccess: (subject: SubjectType) => {
queryClient.setQueryData(SUBJECTS_QUERY_KEY, (old: any) => [...old, subject]);
},
});
return { query, postMutation };
}
Now what is the way to globally handle 401 unauthorized? I would like to navigate user to /login on every unauthorized request. Note that I have more hooks like this tied to other resources.
use the onError callback. You can also do this globally as a callback on the queryCache
const queryClient = new QueryClient({
queryCache: new QueryCache({
onError: error => {
// check for 401 and redirect here
}
})
})

change api fetch into axios call

i am trying to change the api fetch into axios get method i dont know how to do that
const fetchApi = () => {
const request = getAllActivityData();
request
.api({
params: {
customer,
},
})
i want to call api like this using axios
i have added full code in codesandbox it will be helpfull if u can edit the codesand box and make it working
useEffect(() => {
const config = {
headers: {
Authorization: `token
},
};
axios.get("customer/get-all-activity-data/?customer=22", config)
.then((res) => {
console.log(res.data);
});
code sandbox
https://codesandbox.io/s/upbeat-jasper-2jmri?file=/src/App.js:3137-3298
what i have tryed the data is not showning but there are no error .
i am getting data in postman
https://codesandbox.io/s/gifted-montalcini-j7nv7?file=/src/App.js
Do you mean something like this, using async await...
const axiosCallFn = async () => {
let url = '...'
let config = {
headers: {
token: '...'
}
}
try {
let resp = await axios.get(url, config)
return resp.data
} catch(e) {
throw e
}
}
// import the function into your component and use it like so
axiosCallFn()
.then((data) => {
// your functionality here.
})
.catch(() => {
// your error functionality here.
})
and then you can call your axiosCallFn in your useEffect.

How to add a random number in the following URL in reactjs?

I have a project, where I have a create/delete/update.
so in the update component, I have to update the post Title, post Text, and image. so when I update them and press the submit button to save the changes, it works well but it doesn't display the changed image on the UI, till I reload the page, but it does change the image in the file system,
so the URL is like this: http://localhost:3000/Post-Review/307 i want to add a random number for this URL, after the ID
or if there is any other way to solve this problem.
here is the router: <Route path="/Post-Review/:id" exact> <Post /> </Route>
Here is my submitting code:
const submitUpdate = (e) => {
e.preventDefault();
const formData = postToFormData(
postObject,
file,
selectedTags,
deletedTags
);
formData.append("id", actualId);
axios
.put(`${targetServer}/posts/byId/${actualId}`, formData, {
headers: {
"Content-Type": "multipart/form-data",
accessToken: localStorage.getItem("accessToken"),
},
})
.then((res) => {
if (res.data.error) {
alert(res.data.error);
} else {
history.push("/");
}
});
};
thanks
Couldn't you just use a useEffect inside the component and put the random number in the image ref?
src="myimage.jpg?timestamp=123"
the random number could be the timestamp. This way you would be sure that it will always be a unique value.
const timestamp = new Date().getTime()
#Update
Here is the image URL, that is what I am using now.
src={`${targetServer}/posts/image/${postObject.id}`}
if u want to update the UI, you can simply re-fetch the data after the POST request succeeds. React is built for this kind of use.
here is a sample code :
// your post data goes here
const [data, setData] = useState({
...
})
// a method to fetch post data by id
const fetch_data = (post_id) => {
axios
.get(`${targetServer}/posts/byId/${actualId}`, {
headers: {
"Content-Type": "multipart/form-data",
accessToken: localStorage.getItem("accessToken"),
},
}).then((res) => {
if (res.data.error) {
alert(res.data.error);
} else {
// if the update done, then call fetch
setData(res.data)
}
});
}
// the actual update function
const submitUpdate = (e) => {
e.preventDefault();
const formData = postToFormData(
postObject,
file,
selectedTags,
deletedTags
);
formData.append("id", actualId);
axios
.put(`${targetServer}/posts/byId/${actualId}`, formData, {
headers: {
"Content-Type": "multipart/form-data",
accessToken: localStorage.getItem("accessToken"),
},
})
.then((res) => {
if (res.data.error) {
alert(res.data.error);
} else {
// if the update done, then call fetch
fetch_data(post_id)
}
});
}

Resources