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
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' });
}
}
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.
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 })
})
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
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)