No able to update data using react + express - javascript

I'm trying to update data from ui but data does not update though it can be done using postman and in payload data is also being passed.
Here is handle submit function:
enter code here
data.append("thingsTodo", values.thingsTodo);
data.append("minDaysToSpent", values.minDaysToSpent);
data.append("usp", values.usp);
data.append("geoRegion", values.geoRegion.value);
data.append("altitude", values.altitude);
data.append("thingsToConsider", values.thingsToConsider);
try {
const response = await axios.put(`/api/place/${id}`, data).then((data)=>console.log(data,"data"));
controller:
exports.updatePlace = async (req,res) => {
try {
let place = Place.findById(req.params.id)
if(!place){
return res.status(404).json({success:false,message:"Place does not exists"})
}
console.log(req.body)
place = await Place.findByIdAndUpdate(req.params.id,req.body,{new:true})
res.status(200).json({
success:true,
message:"Place Updated Successfully",
place
})
} catch (error) {
return res.status(500).json({
success:false,
error:error.message
})
}
}

Related

recursive calls in Javascript API (Promises)

I am trying to fetch data from one MongoDB collection and with that result, I am passing that value into another function to get the data from GridFS files for same id.
router.get('/employee/:id', async(req,res) =>{
let gID = req.params.id;
var getUser = await User.find({id:gID});
//console.log(res);
console.log(getUser);
if(getUser){
try{
gfs.files.find({objectID:getUser.id}).toArray(async (err, files) => {
if (!files || files.length === 0) {
res.send({
message: "No User Found",
});
} else {
res.send({
message: "data fetched",
data: getUser,
image: files
});
}
});
}catch(err){
res.send({
message:err.code,
data:err
});
}
}else{
res.send({
message:"error in getting the data",
});
}
})
I tried of this but I am not able to get the expected result, I am getting the user information from getUser but I am not able to fetch the file tagged with that user from GridFS. Can anyone tell me where I am lagging and how could I correct this.

Error is thrown and caught in the backend but the fronted React does not catch the error

I was doing a course in MERN Stack and during that I encountered a problem. For one form submission page the backend error handling was done in this way:
router.put('/education' , [auth ,
check('school','School is required').notEmpty(),
check('degree','Degree is required').notEmpty(),
check('fieldofstudy','Field of Study is required').notEmpty(),
check('from','From date is required').notEmpty()
],
async (req,res)=>{
const errors = validationResult(req);
if(!errors.isEmpty()){
return res.json({ errors:errors.array()});
}
const {
school,
degree,
fieldofstudy,
from,
to,
current,
description
} = req.body;
const newEdu = {
school,
degree,
fieldofstudy,
from,
to,
current,
description
}
try {
const profile = await Profile.findOne({ user: req.user.id })
if(profile) console.log('profile found req body is', req.body )
profile.education.unshift(req.body);
console.log('unshifted')
await profile.save();
res.json({ profile })
} catch (err) {
res.status(500).send("Server Error");
}
})
Now if I use Postman to to send some blank raw data as the inputs of the form, It does give back the errors that it is supposed to.
The frontend code used to make this request looks something like this:
export const addEducation = (formData, navigate )=> async dispatch => {
try {
const res = axios.put('http://localhost:5000/api/profile/education',formData)
dispatch({
type: UPDATE_PROFILE,
payload: res.data
});
dispatch(setAlert('Education Added', 'success'))
navigate('/dashboard')
} catch (err) {
const errors = err.response.data.errors;
if (errors) {
errors.forEach((error) => dispatch(setAlert(error.msg, 'danger')));
}
dispatch({
type: PROFILE_ERROR,
});
}
}
The formData is sent through the form page upon Submission of the form.
What this code does is even if all the fields are empty, it just submits the form and sets the alert to 'Education Added' and navigates to '/dashboard'. The database shows no entry of a empty Education field whatsoever. Also the input tags in the form do not have 'required' attribute set.
Why isn't it catching the errors and setting alerts for them?
I am fairly new to MERN so any help will be greatly appreciated!

Axios response data is not saved with useState

While trying to fetch data from my express backend and MySQL database, with my react frontend using axios, it fails to set the fetched data using useState
my frontend function looks like this
const searchUser = () => {
Axios.post("http://localhost:3001/searchUser", {
username: username,
}).then((response) => {
if (response.data) {
setResult(response.data);
}
});
};
and my backend function looks like this
const searchUser = (req, res) => {
const keyword = req.body.username;
db.query(
"SELECT id,username FROM users WHERE username like ?",
"%" + keyword + "%",
(err, result) => {
if (err) {
res.json({ message: err });
console.log(err);
} else {
console.log(result);
res.json({ result });
}
}
);
};
I tried many methods while saving the data with the useState hook, I appreciate any help
While using Promises and then instead of async / await make sure to catch the errors if your fetch fails.
Unless you share with us the whole component that contains the searchUser function and how you defined the state i cannot pin point you on the error.
What i suggest you to do is adding a catch to your fetch by doing the following:
const searchUser = () => {
Axios.post("http://localhost:3001/searchUser", {
username: username,
}).then((response) => {
if (response.data) {
setResult(response.data);
}
}).catch((error) => {
console.error(error);
});
};
If any abnormalities has happened in your request the catch will tell you! Don't underestimate it's power.
Another path you can look into is console logging your output in front end searchUser function just before setting it in the state.
I did solve the problem, just by replacing res.json({ result }); to res.json(result); in the last line in my backend function

How to hold a node api execution till a db query does not return null

Seems rather like an unwanted requirement for a piece of code but in my case this is exactly what I need. I have an api (API-1) that interacts with a third party service. This third party service instead of directly giving me a response that I can forward back to frontend is giving me response on API-2 (With a webhook listener endpoint). I'm saving this API-2 response that I get by listening to the webhook in my database. Now I somehow need this response which is now sitting idol in my database in my API-1 so that I can forward it back to the frontend. If I query the database right away during the flow of the API-1 (Just after consume the third party service API), I'll get null as API-2 is getting the response asynchronously with a webhook (Mostly a gap of 1-2 seconds). So I somehow need to figure out an easy way to await/hold the API-1 flow till the database does not return null/returns back the response I saved from API-2 in the database. I'm not sure if the gap will always be 1-2 seconds hence I can't be using setTimeout for this.
//API-1
const sendPaymentRequest = async (req, res) => {
try {
const payment_reponse = await axios.post(url, body, config);
const { data } = payment_reponse;
console.log("Payment request => ", data);
//Check result i.e response from http listener
const webhookResponse = await MpesaModel.findOne({
conversationId: data.ConversationID
});
console.log('Webhook response => ', webhookResponse); //This is null
res.status(200).json({ message: "Send money request", data });
} catch (error) {
console.log("Error while making a payment request", error);
res
.status(400)
.json({ message: "Error while send payment request", error: error.data });
}
};
//API-2 - This is the webhook which receives the response
const saveWebhookB2C = async (req, res) => {
const { Result } = req.body;
//console.log('Mpesa webhook data received => ', Result);
let saveResponse = new MpesaModel({
...Result,
});
const result = await saveResponse.save();
console.log('B2c mpesa to kenya saved in db => ', result);
res.status(200).send();
};
Just wait until the response is different than null:
let webhookResponse = null;
while (response === null) {
await sleep(1000);
webhookResponse = await MpesaModel.findOne({
conversationId: data.ConversationID,
});
}
The sleep function should be fairly simple (and we use it only to wait one second until the next query):
const sleep = (timeInMilliseconds) => {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(), timeInMilliseconds);
});
};
Note: the while loop will run forever if the answer is always null, so probably you want to add another condition to the while in case the result is always null (maybe a maximum number of tries?).
async function getNotNullResponse({conversationId}){
const webhookResponse = await MpesaModel.findOne({conversationId});
return webhookResponse || getNotNullResponse({conversationId});
}
//API-1
const sendPaymentRequest = async (req, res) => {
try {
const payment_reponse = await axios.post(url, body, config);
const { data } = payment_reponse;
console.log("Payment request => ", data);
//Check result i.e response from http listener
const webhookResponse = await getNotNullResponse({
conversationId: data.ConversationID
});
console.log('Webhook response => ', webhookResponse); //This is not null
res.status(200).json({ message: "Send money request", data });
} catch (error) {
console.log("Error while making a payment request", error);
res
.status(400)
.json({ message: "Error while send payment request", error: error.data });
}
};
//API-2 - This is the webhook which receives the response
const saveWebhookB2C = async (req, res) => {
const { Result } = req.body;
//console.log('Mpesa webhook data received => ', Result);
let saveResponse = new MpesaModel({
...Result,
});
const result = await saveResponse.save();
console.log('B2c mpesa to kenya saved in db => ', result);
res.status(200).send();
};

how can I write a promise within another promise in async/await

I'm quite new to Node.js and I'm trying to build a pagination feature for my "Get all users" page in async/await. But I seem to have bumped into a hurdle and after an extensive research (both here, other sources and even tutorials), I still can't come up with a solution. All the solutions I've seen show me how to do either.
This is the code:
mongoOp.countDocuments({},function(err,totalCount) {
if(err) {
response = {"error" : true,"message" : "Error fetching data"}
}
mongoOp.find({},{},query,function(err,data) {
// Mongo command to fetch all data from collection.
if(err) {
response = {"error" : true,"message" : "Error fetching data"};
} else {
var totalPages = Math.ceil(totalCount / size)
response = {"error" : false,"message" : data,"pages": totalPages};
}
res.json(response);
});
});
I have figured out how to write both countDocuments() and find() functions in async/await to produce results as the following send correct json responses:
The countDocuments() function
try {
totalDocs = await mongoOp.countDocuments();
return res.status(200).json({totalDocs})
} catch (err) {
return res.send(err)
}
};
The find() query:
try {
const users = await mongoOp.find({}, {}, query);
return res.status(200).json({
status: users
});
} catch (error) {
return res.status(400).send(error);
}
However, I don't know how to put them together to produce the needed results.
I would be very grateful if I could be assisted.
You seem to be looking for
try {
const totalCount = await mongoOp.countDocuments();
const totalPages = Math.ceil(totalCount / size)
const data = await mongoOp.find({}, {}, query);
return res.status(200).json({"error":false, "message":data, "pages":totalPages});
} catch (err) {
return res.status(500).json({"error":true, "message":"Error fetching data"});
}

Categories

Resources