I am trying to add DELETE to my api, but am getting a 404: Not Found for everything I try. All of the GET and POST methods work. This is using the "Points" model that contains points, each with a unique id. I am trying to add a call to delete a point by its id.
Action
export function deletePointById(identifier) {
return dispatch => {
return axios.delete('/api/points/' + identifier)
}
}
Route for DELETE (doesn't work)
router.delete('/:identifier', (req, res) => {
Points.remove({
id: req.params.identifier
}), function (err, user) {
if (err) {
return res.send(err);
}
res.json({ message: 'Deleted' });
};
});
Here is an existing GET that works fine
Action
export function getPointsBySession(session){
return dispatch => {
return axios.get('/api/points/session/' + session)
}
}
Route for GET
router.get('/session/:session', (req, res) => {
Points.query({
select: ['id', 'number', 'quadrant', 'level', 'title', 'category'],
where: {sessionId: req.params.session}
}).fetchAll().then(point => {
res.json({ point });
})
});
It looks like your issue might be that theres an extra brace and semicolon ( };) in your code:
router.delete('/:identifier', (req, res) => {
Points.remove({
id: req.params.identifier
}), function (err, user) {
if (err) {
return res.send(err);
}
res.json({ message: 'Deleted' });
}; // <-- HERE
});
You also need to remove the semicolon on the line above the one I added the comment to.
It will look like this:
router.delete('/:identifier', (req, res) => {
Points.remove({
id: req.params.identifier
}), function (err, user) {
if (err) {
return res.send(err);
}
res.json({ message: 'Deleted' })
});
Related
I am trying to push a new object to an array with objects inside another object (see DB Schema here: MongoDB set-up). Trying to push to notes within subtopics[2] object within the topic.
This is the code but it ends up deleting the specified subtopic id:
router.patch('/:topicId/:subtopicId/note', async (req, res) => {
try {
const subtopicNote = await Note.update(
{_id: req.params.topicId},
{subtopics :
{ _id: req.params.subtopicId,
$push: {
notes:
{note: req.body.note}
}
}
}
);
res.json(subtopicNote);
} catch (err) {
res.json({ messsage: err})
}
})
This worked for me :)
router.patch('/:topicId/:subtopicId/note', async (req, res) => {
try {
const subtopicNote = await Note.updateOne(
{_id: req.params.topicId, subtopics : {"$elemMatch": {"_id":req.params.subtopicId}}},
{ $push : {
'subtopics.$.notes': {note: req.body.note}
}
}
)
res.json(subtopicNote);
} catch (err) {
res.json({ message: err})
}
})
I would like to update the shipping property in my MongoDb (CRUD).
Shipping is an array property that contains object[index]. How to update the specific object such as index1 or index2.
This show the shipping property that contains two objects
If I want to update Object only at index 1 on the providerName, how can I do that
exports.updateShpping = (req, res) => {
const {shipping} = req.body;
Shop.findOne({ _id: req.shop._id }, (err, shop) => {
if (!shipping) {
return res.status(400).json({
error: 'shipping is required'
});
} else {
shop.shipping.push(shipping) ;
}
shop.save((err, addShipping) => {
if (err) {
console.log('Shipping ADD ERROR', err);
return res.status(400).json({
error: 'Shipping add failed'
});
}
res.json(addShipping);
});
});exports.updateShpping = (req, res) => {
const {shipping} = req.body;
Shop.findOne({ _id: req.shop._id }, (err, shop) => {
if (!shipping) {
return res.status(400).json({
error: 'shipping is required'
});
} else {
shop.shipping.push(shipping) ;
}
shop.save((err, addShipping) => {
if (err) {
console.log('Shipping ADD ERROR', err);
return res.status(400).json({
error: 'Shipping add failed'
});
}
res.json(addShipping);
});
});
};
I can successfully connect, query & find all of the files that I want from my database, according to my model.
But I can't actually return them as JSON yet... so my question is, how can I return this following result (console.log of res):
Into JSON for my get request?
My model with most vars snipped for brevity:
const fileSchema = new mongoose.Schema({
fileName: { type: String },
versionData: [
{
versionID: { type: Number, required: false
}
]
});
This is my main code where I am trying to return my res as JSON so that my Get request can be properly processed and display the results. I've tried returning JSON.stringify(res), but that didn't seem to work.
// Controller code
findAll = function() {
File.find({}, function(err, res) {
if (err) console.log(err);
else {
// Res is populated successfully
console.log(res);
return res.json(); // JSON.stringify(res)
}
});
};
Router:
// Return all results
router.get("/findAll", ctrlFile.findAll);
Thank you
Hey so I got this working by changing:
findAll = function() {
File.find({}, function(err, res) {
if (err) console.log(err);
else {
return res.json();
}
});
};
To:
findAll = (req, res) => {
File.find({}, function(err, result) {
if (err) console.log(err);
else {
return res.json({ result });
}
});
};
app.get('/clients', (req, res) => {
var clientArray;
MongoClient.connect('mongodb://localhost:27017/Clients', (err, db) => {
if (err) {
return console.log('Unable to Connect');
}
console.log('Connected to Mongodb server');
db.collection('Clients').find().toArray().then((docs) => {
clientArray = JSON.stringify(docs, undefined, 2);
// clientArray = docs;
console.log(clientArray);
}, (err) => {
console.log("ERROR")
});
db.close();
});
res.render('clients.hbs', {
infoArray: clientArray,
name: 'Harshit'
});
});
Here the res.render function is being called before getting the required data from the mongodb database. I want to pass the data fetched as an array to the handlebars template.
{{#each infoArray}}
<h1>{{this.name}}</h1>
{{this.region}}
{{/each}}
Here I am trying to go through the array rendered and display the data.Any Help is appreciated.
Structure of array
[{
"name": "harshit",
"region": "delhi"
},
{
"name": "mendax",
"region": "ecuador"
}
]
Render has to be in callback function :
app.get('/clients', (req, res) => {
var clientArray;
MongoClient.connect('mongodb://localhost:27017/Clients', (err, db) => {
if (err) {
return console.log('Unable to Connect');
}
console.log('Connected to Mongodb server');
db.collection('Clients').find().toArray().then((docs) => {
clientArray = JSON.stringify(docs, undefined, 2);
// clientArray = docs;
console.log(clientArray);
db.close();
res.render('clients.hbs', {
infoArray: clientArray,
name: 'Harshit'
});
}, (err) => {
console.log("ERROR")
db.close();
});
});
});
You are almost there.
This is happening becuse MongoClient.connect(.. is asynchronous. So you res.render executes before that.
What you need is, just move your res.render inside that block
app.get('/clients', (req, res) => {
var clientArray;
MongoClient.connect('mongodb://localhost:27017/Clients', (err, db) => {
if (err) {
return console.log('Unable to Connect');
}
console.log('Connected to Mongodb server');
db.collection('Clients').find().toArray().then((docs) => {
clientArray = JSON.stringify(docs, undefined, 2);
// clientArray = docs;
res.render('clients.hbs', {
infoArray: clientArray,
name: 'Harshit'
});
}, (err) => {
console.log("ERROR")
});
db.close();
});
});
I've the following code to upload a file to Google cloud and afterwards get the public URL. However, it quickly becomes messy when chaining the promises.
Could anyone help with a specific example of chaining the promises in a cleaner way in my example?
let routes = function(imageUploader) {
router.post('/upload',
imageUploader.getMulter().single('image'),
(req, res) => {
imageUploader.uploadFilePromise(req.file.path)
.then((filename, error) => {
if(error) throw new Error(error);
imageUploader.getExternalUrl(filename)
.then((publicUrl, error) => {
if(error) throw new Error(error);
console.log(publicUrl);
})
})
});
return router;
};
I included my ImageUploader class is here as well just as an FYI. Any other best practices suggestions are also much welcome.
const Multer = require('multer'), gcloudStorage = require('./vendors/gcloud');
class ImageUploader {
constructor() {
this.bucket = gcloudStorage;
}
uploadFile(req, res, next) {
if(!req.file) {
next();
}
this.bucket.upload(req.file.path, (err, file) => {
if(err) throw new Error(err);
req.file.publicUrl = this.getExternalUrl(req.file.name)
})
}
uploadFilePromise(path) {
return new Promise((resolve, reject) => {
this.bucket.upload(path, (err, file) => {
if(err) reject(err);
resolve(file.name);
})
})
}
getExternalUrl(filename) {
return new Promise((resolve, reject) => {
this.bucket.file(filename).getSignedUrl({
action: 'read',
expires: '03-17-2025'
}, (err, url) => {
if (err) reject(err);
resolve(url);
});
});
}
storage() {
return Multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/')
},
filename: function (req, file, cb) {
cb(null, Date.now() + file.originalname)
}
});
}
getMulter() {
return require('multer')({ storage: this.storage() });
}
}
module.exports = ImageUploader;
A callback passed to then() receives one and only one argument, not two.
And it can (should) return a value, or another promise, in order to allow further chaining.
If one of the callbacks throws, or returns a rejected promise, you can handle the error with a catch at the end of the chain:
imageUploader.uploadFilePromise(req.file.path)
.then(filename => imageUploader.getExternalUrl(filename))
.then(publicUrl => console.log(publicUrl))
.catch(error -> console.log(error));
Simply regarding chaining promises with .then, I find it cleaner to not add an indent.
ex.
promise
.then(do something)
.then(do something else);