I am trying to send multipart/formdata in my react app. Everytime I hit the POST api using axios, the formdata is always empty.I tried converting to JSON.stringify and key-value method, but nothing seems to work. I do have my headers set as 'Content-Type': 'multipart/form-data'
postList = (e) => {
e.preventDefault();
var postParams;
if(this.state.message && this.state.parent){
postParams = {
message: this.state.message,
chat_m_id: this.state.parent,
depth: (1).toString(),
msg_icon: this.state.msg_icon.name
}
}
else{
postParams = {
message: this.state.message,
chat_m_id: (0).toString(),
depth: (0).toString(),
msg_icon: this.state.msg_icon.name
}
}
console.log(postParams);
let bodyFormData = new FormData();
//approach-one
bodyFormData.append('data',postParams);
//approach-one
// bodyFormData.append('data',JSON.stringify(postParams));
//approach-three
// for (let [key, value] of Object.entries(postParams)) {
// bodyFormData.append(`'${key}'`, JSON.stringify(`${value}`));
// }
console.log(bodyFormData) //this is always empty
axios.post(GlobalVar.BASE_URL+'api/msgtemplate/create', bodyFormData, {headers: GlobalVar.headersFormData})
.then(res => {
console.log(res)
this.props.history.push('/messages')
})
.catch(err => console.log(err.res));
}
I have spent hours on this, please help to solve it.
Here is an example of sending files with axios:
In your case, I have debugged your code here: https://codesandbox.io/s/react-example-ypnbv?fontsize=14&hidenavigation=1&theme=dark
state = { selectedFile: null }
//handler for file change event
fileChangedHandler = event => {
this.setState({ selectedFile: event.target.files[0] })
}
uploadHandler = () => {
const formData = new FormData()
formData.append(
'myFile',
this.state.selectedFile,
this.state.selectedFile.name
)
axios.post('my-domain.com/file-upload', formData)
}
Related
I tried to send the json objects from client to the backend(express) and then save it to mongodb. I can see the json objects sent but with "undefined" at the end.
Client side to send the json object :
setCategoryFile(JSON.stringify(Categories))
const saveStmnt = async (e) => {
e.preventDefault();
const formData = new FormData();
formData.append('categoryFilename', categoryFile)
const config = {
headers: {
'content-type': 'application/json'
}
};
try {
await axios.post("http://localhost:3001/statements", formData,
config, {
});
navigate("/");
} catch (error) {
console.log(error);
}
};
code from backend (express):
export const saveStatement = async (req , res , next) => {
// const info = new StatementSchema(req.body)
console.log('CreditCardAnalysis.js : Perform saveStatement')
console.log(req.body.categoryFile)
let data = new Statement ( {
categoryFile : req.body.categoryFile
})
console.log("perform savedSTmnt...save")
try {
const savedStmnt = await data.save();
if (err)
res.end('Error in saving the statement');
else
{
res.status(201).json(savedStmnt)
res.redirect('/')
}
//res.status(200).json(JSON.stringify(savedProduct));
} catch (err) {
res.redirect('/');
res.end();
}
};
Result from backend :
Database Connected...
{
categoryFilename: '[{"description":"GOOGLE","category":"MISC"},{"description":"AMZN","category":"MERCHANDISE"},{"description":"MCDONALD","category":"DINNING"},{"description":"SAFEWAY","category":"GROCERIES"},{"description":"WISH","category":"MERCHANDISE"},{"description":"99 RANCH","category":"GROCERIES"},{"description":"PARKMOBILE","category":"COLLEGE FEE"},{"description":"CITY OF SAN RAMON","category":"TENNIS"},{"description":"FILA","category":"APPAREL"},{"description":"COMCAST","category":"TELECOM"},{"description":"PEETS","category":"COFFEE"}]'
}
undefined
I am getting my base64 urls and they are correct because if I send only one image its uploaded correctly to cloudinary but when sending multiple images Ii get an error 'ENAMETOOLONG' with error number 4064
here is my graphql resolver
createEvent: async (args: any, req: any) => {
if (!req.isAuth) {
throw new Error("Unauthenticated!!!!");
}
let imagesArr: any[] = [];
for (let i = 0; i < args.eventInput.images.length; i++) {
const result = await cloudinary.uploader.upload(
args.eventInput.images[i],
{
public_id: `${args.eventInput.title}${new Date(
args.eventInput.date
)}${i}`,
folder: "Eventers",
allowedFormats: ["jpeg", "png", "jpg"],
}
);
console.log(result.url, result.public_id);
imagesArr.push({ public_id: result.public_id, url: result.secure_url });
}
const event = new Event({
title: args.eventInput.title,
description: args.eventInput.description,
price: +args.eventInput.price,
date: new Date(args.eventInput.date),
category: args.eventInput.category,
brief: args.eventInput.brief,
tickets: +args.eventInput.tickets,
images: [...imagesArr],
author: req.userId,
});
let createdEvent;
try {
const result = await event.save();
createdEvent = transformEvent(result);
const author = await User.findById(req.userId);
if (!author) {
throw new Error("User not found.");
}
author.createdEvents.push(event);
await author.save();
return createdEvent;
} catch (error) {
console.log(error);
throw error;
}
},
here is the response i get when trying to submit multiple base64 urls
message: "Unexpected error value: { error: { errno: -4064, code: \"ENAMETOOLONG\", syscall: \"open\", path: \"C:\\\\Users\\\\user\\\\Desktop\\\\graphQl maximillian yt course\\\\bookingEvents\\\\backend\\\\data:image\\\\jpeg;base64,\\\\9j\\\\4AAQSkZJRgABAQAAAQABAAD\\\\2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj\\\\2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj\\\\wAARCAQIAkUDASIAAhEBAxEB\\\\8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL\\\\8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6\\\\8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL\\\\8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uP…"
and here is how i transform the images to base
const fileOnChangeHandler = async (e: ChangeEvent<HTMLInputElement>) => {
let files = Array.from(e.target.files!);
files.forEach((file: any) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = async () => {
setImageLinks((prevArr: any) => [...prevArr, reader.result]);
};
});
};
and here is how i send the data to the back end
export const fetchAsyncCreateEvents = createAsyncThunk(
"Events/fetchAsyncCreateEvents",
async (eventInput: Event) => {
const {
title,
category,
description,
brief,
price,
date,
tickets,
images,
} = eventInput;
const { data } = await axios.post<Event>(
API,
{
query: `
mutation{
createEvent(eventInput:{title:"${title}",category:"${category}",description:"""${description}""",brief:"${brief}",price:${price},date:"${date}",tickets:${tickets},images:"${images}"}){
author{
email
}
}
}
`,
},
{
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + localStorage.getItem("token"),
},
}
);
return data;
}
);
I've tried alot of things like adding .replace(/(\r\n|\n|\r)/gm,"") to the for loop at each image array index but it didnt work
and here is one of the base 64 urls
"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAQIAkUDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4"
I deleted more than half of the url so I could submit the question.
i solved the problem it was so simple the problem is i am sending the array of images base64 in a wrong way in graphql mutation
i was sending it with a quotation wrapping it and it turned out you have to use quotations only for strings and for arrays you should json.stringify
export const fetchAsyncCreateEvents = createAsyncThunk(
"Events/fetchAsyncCreateEvents",
async (eventInput: Event) => {
const {
title,
category,
description,
brief,
price,
date,
tickets,
images,
} = eventInput;
const { data } = await axios.post<Event>(
API,
{
query: `
mutation{
createEvent(eventInput:{title:"${title}",category:"${category}",description:"""${description}""",brief:"${brief}",price:${price},date:"${date}",tickets:${tickets},images:${JSON.stringify(images)}}){
author{
email
}
}
}
`,
},
{
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + localStorage.getItem("token"),
},
}
);
return data;
}
);
In console of formvalues values are coming but while sending its not getting in response of console..its become status : 400 and field is required showing but same piece of code is done in expo nd working fine but in react native cli its not working please let me know how can i solve this issue...
export const login = (formValues, actions) => {
return async dispatch => {
dispatch(startSubmitting());
const url = `/auth/login`;
const formdata = new FormData();
formdata.append('email', formValues.email);
formdata.append('password', formValues.password);
console.log(formValues,'formValues');
const response = await api
.post(url, formdata)
.then(res => {
console.log(res,'res');
return res;
})
.catch(error => {
actions.setErrors(error.response.data.error);
console.log(error.response.data.error);
return error.response;
});
dispatch({
type: 'LOGIN',
payload: response,
});
dispatch(stopSubmitting());
if (response && response.data && response.data.access_token) {
await AsyncStorage.setItem('userToken', response.data.access_token,2);
}
};
};
I have problem to update my image using react and axios I convert it in a form data but can’t work it always affiche an error in axios data
This is my method to put data when I remove image in the axios data the request go to the api with success when i put image in the axios data the request is unsuccessful ;(
onSubmit = (e) => {
e.preventDefault();
let fd = new FormData();
fd.append('image', this.state.images, this.state.images.name);
console.log(fd);
const { id, nom} = this.state.patient;
axios.put('/patients/' + this.props.match.params.id, {id, nom,fd})
.then((result) => {
this.props.history.push("/show/" + this.props.match.params.id)
if (result.data != null){
this.setState(this.initialState);
}
});
}
This is my handler image
handleFile(e) {
this.setState({ images: e.target.files[0] });
this.setState({ image: '' });
let reader = new FileReader();
let images = e.target.files[0];
reader.onloadend = () => {
this.setState({ file: images, imagePreviewUrl: reader.result });
}
reader.readAsDataURL(images)
}
I am trying to upload images to an S3 bucket with react and expressjs. When I attempt to upload the image I get a 501 Not Implemented Error. I am using axios to contact the end point I created in the server code.
My react code:
class FileUpload extends Component {
state = {
file: null
};
submitFile = (event) => {
event.preventDefault();
const formData = new FormData();
formData.append('file', this.state.file[0]);
axios.post(`test-upload`, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(response => {
// handle your response;
}).catch(error => {
// handle your error
});
}
handleFileUpload = (event) => {
this.setState({file: event.target.files});
}
render () {
return (
<form onSubmit={this.submitFile}>
<input label='upload file' type='file' onChange=
{this.handleFileUpload} />
<button type='submit'>Send</button>
</form>
);
}
}
export default FileUpload;
My server code:
const uploadFile = (buffer, name, type) => {
const params = {
ACL: 'public-read',
Body: buffer,
Bucket: process.env.S3_BUCKET,
ContentType: type.mime,
Key: `${name}.${type.ext}`
};
return s3.upload(params).promise();
};
app.use('/', (req,res) =>{
res.send(JSON.stringify({ greeting: `Hello!` }));
});
// Define POST route
app.post('/test-upload', (request, response) => {
const form = new multiparty.Form();
form.parse(request, async (error, fields, files) => {
if (error) throw new Error(error);
try {
const path = files.file[0].path;
const buffer = fs.readFileSync(path);
const type = fileType(buffer);
const timestamp = Date.now().toString();
const fileName = `bucketFolder/${timestamp}-lg`;
const data = await uploadFile(buffer, fileName, type);
return response.status(200).send(data);
} catch (error) {
return response.status(400).send(error);
}
});
});
This was done by following a guide on the internet but there seems to be something missing that I just can't figure out.
Figured it out in the end,
axios.post(/test-upload,
should have been
axios.post(http://localhost:3000/test-upload,