Delete error in CRUD RESTful API(Node.js , Express, Mongodb) - node.js

I am using mongoose in this example. While trying to delete ,the following error is being shown to me
Cannot DELETE /5e69e2fde0fa464ee01dd68d
I cannot for the life of me figure out what is going wrong .I am a complete beginner in Node.js , MongoDB and creating RESTful APIs
The code given below is the function I am using to delete .
router.delete('/:id', getSubscriber, async (req, res) => {
try {
await res.subscriber.remove()
res.json({ message: 'Deleted Subscriber' })
} catch (err) {
res.status(500).json({ message: err.message })
}
})
and here is the getSubscriber function
async function getSubscriber(req, res, next) {
let subscriber
try {
subscriber = await Subscriber.findById(req.params.id)
if (subscriber == null) {
return res.status(404).json({ message: 'Cannot find subscriber' })
}
} catch (err) {
return res.status(500).json({ message: err.message })
}
res.subscriber = subscriber
next()
}
Any help is appreciated. Thank you for your time.

router.delete('/:id', getSubscriber, async (req, res) => {
try {
//Here try creating an instance of your model.
//I think your schema is named subscriber so
const deleteSuscriber = await Suscriber.remove({_id:req.params.id});
res.json(deleteSuscriber);
} catch (err) {
res.status(500).json({ message: err})
}
});
Here express will put the variable in req.params form the incoming request.
Hope this works!!
Here you can find the documentation on making CRUD Rest API

Related

deleting an image in a mean stack application

i want to delete the images that i uploaded in the server but every time i get an error
and only the element in the mongodb document are being deleted
this is my code
exports.removeImage = async (req, res) => {
try {
fs.unlinkSync('./images/'+req.filename);
const deleteImage = await Image.findByIdAndDelete(req.params.id)
res.json({ message: 'deleted Image successfully' });
}
catch (err) {
console.log(err);
res.status(500).json({ message: 'Internal server error' });
}
}
i think the problem is in req.filename its returning an undifiened value i tried req.body.filename but still no result
i resolved the problem by adding
const image = await Image.findById(req.params.id)
then i used image.filename in fs.unlinkSync
this is the result :
exports.removeImage = async (req, res) => {
try {
const image = await Image.findById(req.params.id)
fs.unlinkSync('./images/'+image.filename);
const deleteImage = await Image.findByIdAndDelete(req.params.id)
res.json({ message: 'deleted Inspecstib successfully' });
}
catch (err) {
console.log(err);
res.status(500).json({ message: 'Internal server error' });
}
}

response is undefined using Axios and Express

I have this simple post method in back-end:
router.post('/users', async function(request, response) {
try {
const userToRegister = request.body;
const user = await CreateUserService.execute(userToRegister);
return response.json(user);
} catch (err) {
console.log(err);
return response.status(401).json({ message: 'email already registered' });
}
});
At the front end i'm trying to catch the response if the users is already registered, like this:
api.post('users', user.userFields)
.then(response => {
console.log(response)
})
.catch(err => {
console.log(err);
})
In this case, response is always undefined.
If a pass return response.json(err); in backend it works fine.
What am i missing here?
Nevermind guys, found error.
My fail was in the user catch block of CreateUserService.

How do I post both file and data at once in single route in node.js?

I am trying to upload both the image and data in a single node.js route
I found there is something called multipart/form-data but I am unable to use it
I am confused about uploading both data and file can anyone upload the sample code.
However, I am able to upload it by pulling the ID of the Task model and update, Here is the code I did
router.post('/task/avatar/:id', upload.single('taskavatar'), async (req, res) => {
try {
const task = await Task.findById(req.params.id)
console.log(task["name"])
if (!task) {
return res.status(404).send({ "status": false })
}
task["taskavatar"] = req.file.buffer
await task.save()
res.send({ "message": "success" })
} catch (err) { }
}, (error, req, res, next) => {
res.status(400).send({ error: error.message })
})

How to handle the sequelize unique constraint error?

I am new to javascript and I need to handle constraint error in sequelize. I searched related to this topic everywhere, but still, I couldn't get a proper workable answer. My attempt it as follows.
app.post('/api/users', (req, res) => {
try {
console.log(req.body);
User.create(req.body)
.then(user=> res.json(user));
} catch (error) {
console.log("Error: "+error);
}});
Here couldn't catch the exception yet. For a valid user input it is able to post the request. So I just need to know a way to handle the exception.
Was looking around for an answer for this, but was not really satisfied with the two given. If you are looking to return a correct response such as a 403 this is the solution I have came up with.
app.post('/api/users', async (req, res) => {
try {
console.log(req.body);
var user = await User.create(req.body)
return res.status(200).json({ status: 'success', result: res.json(user) })
} catch (error) {
if (error.name === 'SequelizeUniqueConstraintError') {
res.status(403)
res.send({ status: 'error', message: "User already exists"});
} else {
res.status(500)
res.send({ status: 'error', message: "Something went wrong"});
}
}
});
You can use Promise with .then().catch(), or use async/await with try/catch
This is Promise
app.post('/api/users', (req, res) => {
console.log(req.body);
User.create(req.body)
.then(user=> res.json(user))
.catch(err => console.log(err))
});
This is async/await
app.post('/api/users', async (req, res) => {
try {
console.log(req.body);
const user = await User.create(req.body);
res.json(user);
} catch (error) {
console.log("Error: "+error);
}
});
Looks like you're mixing two different styles. If you're using then(), then the try catch block is unnecessary:
app.post('/api/users', (req, res) => {
console.log(req.body)
User.create(req.body)
.then(user => res.json(user))
.catch(error => console.log('Error: ' + error))
})
The other style would be using the async package. With async, your code would look like this:
app.post('/api/users', async (req, res) => {
console.log(req.body)
try {
const user = await User.create(req.body)
res.json(user)
}
catch (error) { console.log('Error: ' + error) }
})
Both methods have their advantages and disadvantages that go beyond this snippet and lot of people use both as appropriate, for example the await approach works only inside a function declared with async like in the second example :async (req, res). In such cases, using then() style promise handling is a better approach

Repeating code for same operation of different datatypes, Express(nodejs) app with mongoose

I am creating an Express rest API that connects to a MongoDB with mongoose. The database has several different datatypes: User, Book, Food and so on. As I am writing endpoints and function for these datatypes. I realized that I am repeating a lot of the same code, for example, for the code below:
// Book.js
import Book from './models/Book'
function deleteById (req, res, next) {
Book.findByIdAndRemove(req.params.id, function (err) {
if (err) {
let error = new Error('Failed to delete an book in database')
error.statusCode = 500
return next(error)
}
res.json({
success: true,
message: 'Book deleted successfully'
})
})
}
I can just change Book to User or Food and the same code can be used. Which results in a lot of repeating code that looks like this:
// Food.js
import Food from './models/Food'
function deleteById (req, res, next) {
Food.findByIdAndRemove(req.params.id, function (err) {
if (err) {
let error = new Error('Failed to delete an food in database')
error.statusCode = 500
return next(error)
}
res.json({
success: true,
message: 'Food deleted successfully'
})
})
}
So I was wondering if there is a way to generate the functions so that I don't need to repeat the code for the deleteById function for each type of data. What would be the best practice? Or is it a bad practice to try to generate the functions and repeating is necessary?
Any help would be really appreciated, thanks in advance.
You can create a delete middleware. In the below code I pass the model delete function as argument and I return a middleware. In that middleware function I call the delete function that came dynamically.
var deleteMiddleWare = function(deleteByIdFunc, name) {
var deleteId = req.params.id;
if (!deleteId)
res.json({
success: false,
message: `Please provide ${name} id.`
})
return function(req, res, next) {
deleteByIdFunc(req.params.id, function(err) {
if (err) {
let error = new Error(`Failed to delete ${name} in database`)
error.statusCode = 500
return next(error)
}
res.json({
success: true,
message: `${name} deleted successfully`
})
})
}
}
router.get(/user/delete /: id, deleteMiddleWare(User.deleteById, 'User'))
router.get(/food/delete /: id, deleteMiddleWare(Food.deleteById, 'Food'))
After a lot of research, I found the best way to be using a class constructor and pass in datatype as a variable:
class BaseController {
constructor (type, name) {
if (!type || !access) {
throw new Error('Must define datatype')
}
this.datatype = type
this.name = name
this.deleteById = this.deleteById.bind(this)
}
deleteById (req, res, next) {
let name = this.name
this.datatype.findByIdAndRemove(id, function (err) {
if (err) {
let error = new Error(`Failed to delete ${name} in database`)
error.statusCode = 500
return next(error)
}
res.json({
success: true,
message: `${name} deleted successfully`
})
})
}
}
And in the router file, we can just call
const food = new BaseController(Food, 'Food')
router.get('/food/delete/:id', food.deleteById)

Resources