I'm not sure what I'm doing wrong here? The GET works fine with the same info, but the DELETE keeps giving me a 500 Internal server error, and my server logs say, "StoredProduct.delete is not a function"
For the sake of this post, I'm including the GET route and GET JS below, just to show those are working, so I think my routes are set up correctly?
These are my routes
router.get('/:productID', (req, res, next) => {
StoredProduct
.findOne({
_id: req.params.productID
})
.then(product => {
res.status(201).json(product);
});
});
router.delete('/:productID', (req, res) => {
StoredProduct
.delete(req.params.productID);
res.status(204).end()
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
});
And this is my JS
$.ajax({
type: 'GET',
url: '/products/' + productID,
success: function(product) {
$editProdName.append(`${product.name}`);
$addPrice1.val(product.prices[0].price);
$addPrice2.val(product.prices[1].price);
$addPrice3.val(product.prices[2].price);
$selectedUnit.val(product.size);
}
});
$('#deleteme').on('click', function(e) {
e.preventDefault();
console.log(productID);
$.ajax({
type: 'DELETE',
url: '/products/' + productID,
success: function(){
console.log('yippee');
}
});
});
You can use mongoose.deleteOne() and search by id and delete:
router.delete('/:productID', (req, res) => {
StoredProduct
.deleteOne({ _id: req.params.productID}).then(data =>
res.status(204).end()).catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
});
Do you use mongoose?
If so try to
StoredProduct.deleteOne({ id: req.params.productID }, function (err) {});
Also from http://api.jquery.com/jquery.ajax/:
Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are removed as of jQuery 3.0. You can use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.
Related
I am creating URL Shortener Microservice application.I have a mongodb cluster that i save my all url links. I am successfully connect to database.I am making post request to save my posted url. Related code is here
app.post('/api/shorturl', (req, res) => {
const bodyUrl = req.body.url;
const something = dns.lookup(
urlParser.parse(bodyUrl).hostname,
(error, address) => {
if (!address) {
res.json({ error: 'Invalid URL' });
} else {
const url = new Url({ url: bodyUrl });
url.save((err, data) => {
res.json({
original_url: data.url,
short_url: data.id,
});
});
}
}
);
});
So, I can save my new url in database succesfully.Here also related cluster after post request
But my problem is with get request. I dont know why i cant find the url links by id. Here also my get request
app.get('/api/shorturl/:id', (req, res) => {
// const id = req.body.id;
Url.findById({ _id: req.body.id }, (err, data) => {
if (!data) {
res.json({ error: 'Invalid URL' });
} else {
res.redirect(data.url);
}
});
});
You need to either use:
Url.findOne({ _id: req.params.id }, (err, data) => {
if (!data) {
res.json({ error: 'Invalid URL' });
} else {
res.redirect(data.url);
}
});
or:
Url.findById(req.params.id, (err, data) => {
if (!data) {
res.json({ error: 'Invalid URL' });
} else {
res.redirect(data.url);
}
});
findOne takes an object as the argument (like you have).
findById just takes the ID as the argument.
You seem to be combining the two options.
Edit: I found another issue with your code, you are trying to pull the id from req.body.id, but in this case, you need to use req.params.id. The code in my post has been updated.
I am doing a login system in NodeJS with a Mongo database, so I try to look in my collection if the user exist. For my tests, I have a user registered, and I'm trying to find him.
My problem is that findOne method return the full user' data as I wish, but in the error parameter, not in the results parameter, and I have no logs to understand why...
Did somebody know why ?
Here is my code:
app.post('/login', (req, res) =>{
console.log(req.body.identifier);
console.log(req.body.password);
client.connect().then(() => {
let newUser = {identifier : req.body.identifier}
res.redirect(req.body.locator)
return client.db(`${process.env.MONGODB}`).collection(`${process.env.MONGOCOLLECTION}`).findOne(newUser).then((err, res) => {
if (err){
console.log("ERROR: "+err.role)
throw err;
}else if(res){
console.log("user found");
console.log(res.role)
}
})
}).catch( e => { console.error(e) }).then(() => {
console.log("--------------------------------");
})
})
And this is what I got :
mail#mail.com
azer
ERROR: USER
{
_id: 6087d850ad9f6f2e0ce97045,
identifier: 'mail#mail.com',
password: '7657d9148a5720dcf4eb4b8bc998498e5d701ce7beb302f398c3d5c0dbd0f857f824b7bfaa45c2a8aba4f85c4ab8b12c99bfb28328e72a89afe11326dc1d3a38349c1c36790a24c910528ada34529e6736ae45f0e5d87ce6b109207e21169bc9b4056fff',
role: 'USER',
sign_up: 2021-04-27T09:24:32.616Z,
name: 'Test',
firstName: 'Test'
}
--------------------------------
This occurs because your code mixes Promises and callbacks. In particular:
findOne(newUser).then((err, res) => {
// (this does not work because .then() takes a function with 1 argument)
})
Promises have a built-in error handling mechanism where a resolver can either resolve or reject the promise, triggering the .then() (success) or the .catch() (failure) branch.
See the note at the top of the relevant manual page. Also, MongoDB provides a short guide on Promises vs. callbacks - pay attention especially to this snippet:
collection
.updateOne({ name: "Mount McKinley" }, { $set: { meters: 6190 } })
.then(
res => console.log(`Updated ${res.result.n} documents`),
err => console.error(`Something went wrong: ${err}`),
);
Note how .then() accepts two functions above - these are separate callbacks for the "success" case and the "error" case.
Read - Promises and Callbacks
Here you're using promise - then will give the result and catch will give the error.
client.db(`${process.env.MONGODB}`)
.collection(`${process.env.MONGOCOLLECTION}`)
.findOne(newUser)
.then( res => { ... }) // result
.catch(err => { ... }) // error
Callback style
client.db(`${process.env.MONGODB}`)
.collection(`${process.env.MONGOCOLLECTION}`)
.findOne(newUser, (err, res) => { ... })
The mongodb was returning the data, and the data was taken as first argument in the then block named as err, try changing to this:
app.post("/login", (req, res) => {
console.log(req.body.identifier);
console.log(req.body.password);
client
.connect()
.then(() => {
let newUser = { identifier: req.body.identifier };
res.redirect(req.body.locator);
return client
.db(`${process.env.MONGODB}`)
.collection(`${process.env.MONGOCOLLECTION}`)
.findOne(newUser, (err, res) => {
if (err) {
console.log("ERROR: " + err.role);
throw err;
} else if (res) {
console.log("user found");
console.log(res.role);
}
});
})
.catch((e) => {
console.error(e);
})
.then(() => {
console.log("--------------------------------");
});
});
Function that i want to test:
const homepageGet = (req, res, next) => {
Product.find(function (err, products) {
if (err) {
console.log(err);
next(err);
} else {
res.render('allProducts', { title: res.__('allProducts.title'), response: res, products: products });
}
});
};
I want to test if this function is actually sending products to the view. This is the test i wrote:
describe('Home page with all products', () => {
it('shows all products', (done) => {
chai.request(server)
.get('/')
.end((err, response) => {
response.body.should.have.property('products');
done();
});
});
});
This test fails and shows the following error message:
Uncaught AssertionError: expected {} to have property 'products'
How do I fix this?
this is my code:
router.post('/update_todo', async (req, res) => {
const { todoId, userId, complete } = req.body;
try {
const todo = await Todo.findOneAndUpdate(
{ _id: todoId, userId },
{ $set: { complete: !complete } },
{ new: true } // return latest
).populate('userId', '_id');
console.log('todo pdated', todo)
res.json({ todo })
} catch (error) {
res.status(400).json({ error })
}
})
when i try to log, it's returning twice?
todo pdated null
todo pdated { complete: true,
_id: 5c003223ec8c1350b8c77b4f,
text: 'wearasdasd asd 2222',
userId: { _id: 5bf3b0b676bcc8176422e94e },
createdAt: 2018-11-29T18:38:27.156Z,
updatedAt: 2018-11-29T23:31:57.022Z,
__v: 0 }
what is causing this code to return twice when i am using async/await?
try this :
router.post('/update_todo', async (req, res) => {
const { todoId, userId, complete } = req.body;
try {
Todo.findOneAndUpdate({_id: todoId,userId:userId},{$set:{complete: !complete}}, {new: true}, (err, doc) => {
if (err) {
console.log("Something wrong when updating data!");
}
console.log('todo updated', doc)
res.json({ doc })
});
} catch (error) {
res.status(400).json({ error })
}
})
I have a guess, although your question lacks enough data to be sure: I don think it is an issue with async/await, but your code is running twice because browser makes Preflight OPTION request:
... "preflighted" requests first send an HTTP request by the OPTIONS
method to the resource on the other domain, in order to determine
whether the actual request is safe to send.
To prevent that, I suggest this piece of code in a CORS scenario that returns the OPTIONS request before the system reaches out your business logic:
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", '*');
...
if (req.method === 'OPTIONS') {
res.sendStatus(200);
}
else {
next();
}
});
I am making a quite easy CRUD application in MEAN stack.
I have succesfully done all but Update function. Problem is not with request itself but inability of Node server to respond. Request is making changes to database as requested and I even eget a { n: 1, nModified: 0, ok: 1 } response from mongojs.
However, I am unable to send it back to Angular frontend.
I try res.json() but it won't all allow me as it is a not a function? But I am succesfuly doing res.json in create, delete and read. In network tab in developers console, request seems to be pending and after like 30 seconds it throws an error.
No luck with postman either.
How can I send a response to frontend?
// Error handling
const sendError = (err, res) => {
response.status = 501;
response.message = typeof err == 'object' ? err.message : err;
res.status(501).json(response);
};
// Response handling
let response = {
status: 200,
data: [],
message: null
};
// Update log <-- doesn't send response but works
router.put('/update/:id', (req, body, res) => {
console.log("Received UPDATE request");
console.log(req.params.id);
const bodyToUpdate = {
'_id': mongojs.ObjectId(req.params.id),
'week': req.body.week,
'type': req.body.type,
'text': req.body.text,
'days': req.body.days
};
console.log(bodyToUpdate);
db.logs.update({
_id: mongojs.ObjectId(req.params.id)}, bodyToUpdate, (err, res) => {
if (err) return next(err);
response.data = res;
res.json(response);
console.log(response);
});
});
// Delete log <--does work without problems
router.post('/delete/:id', (req, res) => {
console.log("Received DELETE request");
console.log(req.params.id);
db.logs.remove({
_id: mongojs.ObjectId(req.params.id)}, (err, users) => {
if (err) return next(err);
console.log(response);
response.data = users;
res.json(response);
});
});
Service API frontend
deleteLog(id) {
return new Promise((resolve, reject) => {
this._http.post('/api/delete/' + id , id)
.map(res => res.json())
.subscribe(res => {
resolve(res);
console.log(res);
}, (err) => {
reject(err);
});
});
}
updateLog(logToUpdate) {
return new Promise((resolve, reject) => {
this._http.put('/api/update/' + logToUpdate._id, logToUpdate)
.map(res => res.json())
.subscribe(res => {
resolve(res);
// console.log(res);
}, (err) => {
reject(err);
});
});
}
As #JithinSebastian correctly pointed out - I should not have 3 arguments in put request. I also had to change name of callbacks in mongo update function because I already used res in router function callback.
// Update log
router.put('/update/:id', (req, res) => {
console.log("Received UPDATE request");
console.log(req.body);
const bodyToUpdate = {
'_id': mongojs.ObjectId(req.params.id),
'week': req.body.week,
'type': req.body.type,
'text': req.body.text,
'days': req.body.days
};
db.logs.update({
_id: mongojs.ObjectId(req.params.id)
}, bodyToUpdate, (err, logs) => {
if (err) return next(err);
response.data = logs;
res.json(response);
console.log(response);
});
});