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
Related
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;
}
);
I want to fetch data from mongodb by using document property similarly like findById() method I can fetch with query but I want to display data on another page
This is my api code for fetching data
const User = require("../models/User");
const Image = require("../models/Image");
const addImage = async (req, res, next) => {
const newImage = new Image({ userId: req.user.id, ...req.body });
try {
const saveImage = await newImage.save();
res.status(200).json("Image uploaded");
} catch (error) {
next(error);
}
};
// GETPRODUCTBYID :-
const getImage = async (req, res) => {
try {
const image = await Image.findById(req.params.id);
res.status(200).json(image);
} catch (error) {
res.status(500).json(error);
}
};
// GET ALL PRODUCTS :-
const getAllImages = async (req, res) => {
const qNew = req.query.new;
const qCategory = req.query.category;
const qBrand = req.query.brand;
try {
let images;
if (qNew) {
images = await Image.find().sort({ createdAt: -1 }).limit(1);
} else if (qCategory) {
images = await Image.find({
categories: { $in: [qCategory] },
});
}
if (qBrand) {
images = await Image.find({ brand: "Honda" });
} else {
images = await Image.find();
}
res.status(200).json(images);
} catch (error) {
res.status(500).json(error);
}
};
// GET IMAGES BY BRAND :-
const getImagesByBrand = async (req, res) => {
const qBrand = req.query.brand;
try {
const images = await Image.find( {brand: qBrand});
res.status(200).json(images);
} catch (error) {
res.status(500).json(error);
}
};
module.exports = Object.freeze({
addImage,
getImage,
getImagesByBrand,
getAllImages,
});
Structure of document in mongo db
Document
_id
brand
I want to fetch data with brand property and show it on new page it is possible?
I am stuck on this problem for 2 days. I am sending POSTrequest from frontend to the backend (and other GET requests too but the problem is only with POST). However, when my data goes to the backend it does not post anything to the rest api even though response is 200 OK. That's why when in response it should have given the posted data, it can't find it and gives null. This is my POST code in backend index.js:
const { response, request } = require('express');
require('dotenv').config()
const express = require('express');
const morgan = require('morgan');
const Contact = require('./models/contact.cjs');
const cors = require('cors')
const app = express();
app.use(express.json())
app.use(express.static('build'))
app.use(cors())
morgan.token('body', req => {
return JSON.stringify(req.body)
})
app.use(morgan(':method :url :status :res[content-length] - :response-time ms :body'));
const generateId = () => {
const randNum = Math.floor(Math.random() * 5000)
return randNum;
}
app.post('/api/persons', (req, res) => {
const body = req.body
console.log(body)
if (!body.name || !body.number) {
return res.status(400).json({
error: "missing data"
})
} else if (Contact.find({name: body.name})) {
Contact.findOneAndUpdate({name: body.name}, {$set: {number: body.number}}, {new:true})
.then(updatedContacts =>
res.json(updatedContacts)
)
.catch(err => console.log(err))
} else {
const contact = Contact({
id: generateId(),
name: body.name,
number: body.number,
date: new Date()
})
contact.save()
.then(savedContact => {
console.log(savedContact)
res.json(savedContact)
})
.catch(err => {
console.log(err)
})
}
})
const PORT = process.env.PORT
app.listen(PORT, () => {
console.log(`Server is working on ${PORT}`)
})
and this is how my frontend sends data to backend: contacts.js:
const create = (newObject) => {
const readyToPost = {
method: 'post',
url: `${baseUrl}`,
data: newObject,
headers: {'Content-Type': 'application/json'},
json: true
}
const request = axios(readyToPost)
return request.then(response => {
console.log(response.data)
return response.data
})
.catch(err => {
console.log(err)
})
}
And this is my react app's frontend.
Any ideas about why my data becomes null?
Any help would be appreciated!
Due to the synchronous nature of your code, the condition Contact.find({name: body.name}) was always returning the Query object which is true due to which the else if block was getting executed even when there was no such document. After entering the else if block, since there was no match, so findOneAndUpdate() was returning null.
Use findOne() instead of find(). find() returns a cursor which is empty but true whereas findOne() returns the first document matched (if matched) or else it will return null (if not matched).
// index.js (Backend)
app.post("/api/persons", async (req, res) => {
const body = req.body;
if (!body.name || !body.number) {
return res.status(400).json({
error: "missing data",
});
}
// Using findOne() instead of find(). Returns null if record not found.
const existing = await Contact.findOne({ name: body.name });
if (existing) {
Contact.findOneAndUpdate(
{ name: body.name },
{ $set: { number: body.number } },
{ new: true }
)
.then((updatedContacts) => {
console.log(updatedContacts);
res.status(200).json(updatedContacts);
})
.catch((err) => console.log(err));
} else {
const contact = Contact({
id: generateId(),
name: body.name,
number: body.number,
date: new Date(),
});
contact
.save()
.then((savedContact) => {
console.log(savedContact);
res.status(201).json(savedContact);
})
.catch((err) => {
console.log(err);
});
}
});
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)
}
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,