Delete item from mongoDB from client side - node.js

I've created a React app where you can post vinyls you have in your collection. Now I've implemented a button that is able to remove the selected item from the DOM but I also want the specific item to beremoved from the database. I'm using node with mongoose and that's (for now) my delete route:
vinylsRouter.delete('/:id', (req, res) => {
const id = req.params.id
Vinyl.findByIdAndDelete(id)
.then((deletedVinyl) => {
console.log(deletedVinyl)
})
.catch((error) => {
res.status(500).send(error);
})
});
I also tried to store the id of the specific vinyl _id into a variable and then delete it. So I also created a get route to try to get the _id of the vinyl.
vinylsRouter.get('/:id', authenticateJWT, (req, res) => {
const id = req.params.id;
Vinyl.findById(id, { __v: 0, updatedAt: 0, createdAt: 0 })
.then((user) => {
res.send(user)
})
.catch((error) => {
res.status(500).send(error)
})
});
But now I don't know how to code in the client side to make that when an user clicks in the delete button, it sends something to get the id of the vinyl and then delete it.

First put some response when the delete works:
vinylsRouter.delete('/:id', (req, res) => {
const id = req.params.id
Vinyl.findByIdAndDelete(id)
.then((deletedVinyl) => {
res.status(200).send(deletedVinyl);
})
.catch((error) => {
res.status(500).send(error);
})
});
If are you trying to do a API You can use express/nodejs, and do res.status(200).json({message: "my message"}).
Second you can use a library like axios:
axios.delete(`http://localhost:xyz/vynils/`, { id })
.then(res => {
console.log(res);
console.log(res.data);
})
https://www.digitalocean.com/community/tutorials/react-axios-react
And send for the server when the users click in the delete button.
You can use postman to test your delete endpoint before you use this on client-side (frontend), remember select delete in the dropbox and put a auth token (JWT) in the Authorization tab, or you can remove, only for test the auth middleware:
Say me if is this what you want to do.

app.delete('/product/:id', async (req, res) => {
const id = req.params.id;
const query = { _id: ObjectId(id) };
const result = await productCollection.deleteOne(query);
res.send(result);
})

Related

req.users undefined react express

so im getting an undefined response when fetching my api and i really dont know why
this is the function calls in the component
const init = usersId => {
getUser(usersId).then(data => {
if (data.error) {
setValues({ ...values, error: data.error });
} else {
// populate the state
setValues({
...values,
username: data.username,
email: data.email,
formData: new FormData()
});
}
});
};
this is the api call in react
export const getUser = usersId => {
console.log('ok')
console.log(usersId)
return fetch(`${API}/users/${usersId}`, {
method: 'GET'
})
.then(response => {
return response.json();
})
.catch(err => console.log(err));
};
at this point im getting the user id correctly but when the fetch is running i get an error that i cant read property of undefined so, there is the express server endpoint
router.get('/users/:usersId',
read_);
and here is the controller
userCtrl.read_ = (req, res) => {
console.log(req.users)
console.log('test')
return res.json(req.users);
};
i really dont know what im doing wrong at this point
You can't get req.user, cos you're not sending req.user.
You are only sending userId and you can only get it via req.params
like this
req.params.userId
What you want to do is use the userId to get the associated user from your DB
if you want req.user you'll have to find user from id.
you can get id by req.params.userId
after getting userdata from database assign user object to req.user
like this: req.user = user;
then you can access req.user

findOneAndDelete Mongoose not working MERN stack

GoodDay Experts,
I've tried following code but it did not work, and it gives me null value.. maybe my routes are wrong but basically it works the way on other routes... and here is my backend for delete case: manage.js/actions
export const removeRecipient = (payload) => async (dispatch) => {
try {
const res = await axios.delete(
`${_config.MAT_URL}/api/1/customer/delete`,
payload
);
dispatch({
type: DELETE_CUSTOMER,
payload: res.data,
});
} catch (err) {
dispatch({
type: POST_ERROR,
payload: { err },
});
}
};
and for my routes which is the mongoose query for findOneAndDelete, under customer.js :
router.delete("/delete", (req, res) => {
Customer.findOneAndDelete({ _id: req.params.id }, (err, Customer) => {
if (!err) {
res.json({ msg: "customer deleted", deleted: Customer });
} else {
console.log("Error removing :" + err);
}
});
});
And for the front end im using "AiOutlineDelete" which was coded as :
const handleDelete = (id) => {
console.log('delete')
removeRecipient(id)
}
<a
id={`delete-${rowIndex}`}
className="anchor-action-delete"
href="#foo"
onClick={(e) => {
e.preventDefault();
handleDelete(row);
}}>
thanks have a great day
There are 2 problems in your code:
req.params.id is meant for urls of the form /delete/:id which is obviously not your route, you should change it to req.query.id instead which matches query parameters in the url such as /delete?id=123.
The default type of _id is ObjectId, under the assumption you did not change this you need to cast your req.query.id which is type string to ObjectId.
It looks like you're using mongoose so here's mongoose syntax:
const mongoose = require("mongoose");
router.delete("/delete", (req, res) => {
Customer.findOneAndDelete({ _id: new mongoose.Types.ObjectId(req.query.id) }, (err, Customer) => {
if (!err) {
res.json({ msg: "customer deleted", deleted: Customer });
} else {
console.log("Error removing :" + err);
}
});
});
For nodejs native Mongo package:
import {ObjectId} from "mongodb";
...
new ObjectId(req.query.id)
I dont see you sent the id to the backend but you are trying to retrieve it from req.params.id try passing the id like "delete/:id" at the end of the link and specify this in the routes aswell.
if that doesnt fix try the below code this for routes
if nothing works check this, In the component you need to send the id(object id) but i see "row" what is the value of row? if the row value is not the id in the database then it wont delete. if this your issue try inspecting the code by keeping breakpoints or write a console.log() to check the value of "row" .
try {
const removedProject = await Customer.remove({
_id: req.params.id
})
res.json(removedProject)
} catch (err) {
res.json({
message: err
})
}

mongodb data updated, but axios is fetching old data

When a user updates his profile in editProfile component,the data is updated in the server and the user is redirected to the userProfile component. Now in the userProfile, users data is fetched from the server. Here i am getting the old data. But if i refresh the page, i get the updated data.
//api
router.post('/:uid/edit', (req, res) => {
const updatedUser = {
name : req.body.name,
avatar : req.body.avatar,
bio : req.body.bio
};
console.log('updateduser',updatedUser);
User.findOneAndUpdate({uid: req.params.uid}, {$set: updatedUser},
{"new":true})
.then(user => {
res.json(user);
console.log(user);
})
.catch(err => {
console.log('er',err);
});
});
//action
export const usersFetchData = (url) => {
return (dispatch) => {
dispatch(userIsLoading(true));
axios
.get(url)
.then(res => {
if(!res){
throw Error(res.statusText)
}
dispatch(userIsLoading(false));
console.log(res.data); //getting old data
return res.data;
})
.then(users => {
console.log('users',users);
dispatch(usersFetchDataSuccess(users))
})
.catch(() => dispatch(userHasErrored(true)));
}
}
Most likely this is due to axios caching. See what you have in the axios settings and if
'Cache-Control': 'no-cache'
is set. Usually via:
var config = {headers: {'Content-Type': 'application/json','Cache-Control' : 'no-cache'}};
axios.get('/get', config) // <-- config
If this does not work you can always just append a timestamp to the request to make sure it always makes a request.

Firebase Admin SDK roles

I am setting up the Firebase Admin SDK in a NodeJS, Express API.
I have added an endpoint that allows me to create a user -
route.post('/create', (req, res) => {
const { email, password } = req.body
fbseAdmin.auth().createUser({ email, password })
.then((userRecord) => {
res.status(200).json({ userRecord })
})
})
What I would like to do however is ensure a user has roles so I can provide Authorisation checks on some services.
I do not understand how I can achieve this though? I was thinking perhaps I add an entry to the realtime database, something like -
users/uid/roles/<role name>: true
However I am not sure if I missing something. Also, if this is the case and I do need to do this, would I do this something like -
route.post('/create', (req, res) => {
const { email, password } = req.body
fbseAdmin.auth().createUser({ email, password })
.then((userRecord) => {
fbseAdmin.database()
.ref('users')
.child(`${userRecord.uid}/roles`)
.set({
admin: true
})
res.status(200).json({ userRecord })
})
})
This seems a little brittle to say the least.
Also, as this entry isn't part of the user object, I would need to look up in the realtime db everytime I want to verify this? Is that correct?
You should look at how to set a custom claim against a user.
route.post('/create', (req, res) => {
const { email, password } = req.body
fbseAdmin.auth().createUser({ email, password })
.then((userRecord) => {
fbseAdmin.auth().setCustomUserClaims(userRecord.uid, { admin: true })
.then(() => {
res.status(200).json({ userRecord })
})
})
})

Setting a unique user nickname in node express app

I have a user profile collection in which I have the following fields:
member_id
userhandle
height
weight
I register a user with passport and generate a unique member_id for each user which is later used for getting the profile page populated and also for referrals. Following is the get profile route where user can change their details:
// Get User Profile Settings route
router.get('/profilesettings/:member_id', (req, res) => {
Profile.findOne({ member_id: req.params.member_id })
.then(profile => {
res.render('users/profilesettings', { profile: profile });
})
.catch(error => {
console.log('could not find profile');
});
});
Once this page is loaded the user can change their details and use the submit button to update their data. Following is the code for the put request:
router.put('/profilesettings/:member_id', (req, res) => {
Profile.findOne({ member_id: req.params.member_id })
.then(profile => {
profile.userhandle = req.body.userhandle;
profile.weight = req.body.weight;
profile.height = req.body.height;
profile.mobile = req.body.mobile;
profile.save()
.then(updatedProfile => {
req.flash('success_msg', 'Profile updated successfully');
res.redirect('/user/userdashboard');
})
.catch(error => {
console.log(error);
});
})
.catch(error => {
console.log('could not find record');
});
});
What I want to do is ensure that the userhandle is always unique, so if the user enters a userhandle which is already taken by someone else in the profile collections there should be an error and the form should not submit. I am totaly stumped on how to put in a logic which does the following:
1- Checks if there is a difference in the userhandle submitted and the one already stored in the collection
2- Checks if the userhandle which came in the request already exists or not
3- if not then sets the userhandle to the new value and save
4- if it does it creates and error and redirects.
Would appreciate any advise. I know it's a small thing for you pros but I am learning Node and express :-)
After you have confirmed if the member exists or not, you can do a 'count' query to check if the 'userHandle' exists or not. If the userHandle already exists you can return a 4xx status code. Otherwise, save it in the db. It would look something like this...
router.put('/profilesettings/:member_id', (req, res) => {
Profile.findOne({ member_id: req.params.member_id })
.then(profile => {
Profile.count({userhandle: req.body.userhandle})
.then(count => {
if(count != 0){
//return the error code
}
else{
//proceed with your normal flow
profile.userhandle = req.body.userhandle;
profile.weight = req.body.weight;
profile.height = req.body.height;
profile.mobile = req.body.mobile;
profile.save()
.then(updatedProfile => {
req.flash('success_msg', 'Profile updated successfully');
res.redirect('/user/userdashboard');
})
.catch(error => {
console.log(error);
});
}
}).catch(err => {
console.log(err);
});
})
.catch(error => {
console.log('could not find record');
});
});

Resources