Can't bind params in nodejs - node.js

I want to bind params in node js and this is my code but shows some erros,
app.get("/single/:id", async (req, res) => {
let id = req.params.id;
console.log(id);
try{
const singleMovie = await Movies.findById(id)
res.render("single", {
singleMovie: singleMovie
});
}catch(err){
console.error(err.message);
}
});
shows me this warning,
Cast to ObjectId failed for value "undefined" at path "_id" for model
"Movies" and id is undifined
any way to fix this?

In your code res.render("single", { should be res.json("single", {

Try the code below... sending the response in json just to test it....
if you get the same error you are getting, then there is a problem somewhere in your code. Because The block of code you posted looks fine!
app.get("/single/:id", async (req, res) => {
let id = req.params.id;
console.log(id);
try{
const singleMovie = await Movies.findById(id)
res.json({
singleMovie: singleMovie
});
}catch(err){
console.error(err.message);
}
});
Also make sure you are using nodejs -v 8+ and mongoose -v 5+

Related

How to take and output documents from a MongoDB database with NodeJS?

I've been working on one of my first API projects with NodeJS, Express and MongoDB. I can save new documents into the database with collection.insertOne(newDocument) method but I can not take existing documents and output them using collection.find({}).
Can you please help me:')
export const visualizeUser = (req, res) => {
console.log("you are searching the user with username " + req.body.username);
users.find({username: 'yavuz'}, (err, data) => {
if(err)
console.log(err);
else
console.log(data);
});
}
thats the code I have written.
MongoInvalidArgumentError: Argument "options" must not be function
and that is the error I am getting.
Your help is really appreciated.
Like error message is saying, you cannot pass function as options argument.
Look here: docs
Your code should look like this:
const visualizeUser = async (req, res) => {
try{
console.log("you are searching the user with username " +
req.body.username);
let data = await users.find({username: 'yavuz'});
console.log(data)
} catch(e) {
console.log(e)
}
}

Supabase & ExpressJS having issues with errors

I have been playing around with ExpressJS I normally use FastAPI. I can't seem to generate an error using Supabase.
I have this endpoint
app.delete('/api/delete-book/:id', cors(corsOptions), async (req, res) => {
const {data, error} = await supabase
.from('books-express')
.delete()
.match({id: req.params.id})
if (error) {
res.status(400).send({message: `ERROR! ${error.message}`})
}
if (data)
res.send({
message: `Book ID ${req.params.id} has been deleted from the database`,
})
})
This works when it comes to deleting a book via an ID. However if I enter an invalid ID I get the data if block firing.
There is no book with an ID of 222 in the database, I would expect the error to fire but its just null
Any ideas here?
This is expected behaviour; not matching any rows is not considered an error condition in postgres.
If you'd like to check if any rows were deleted, you can use something akin to (on supabase-js 2.x):
const { data, error } = await supabase.from('books-express')
.delete()
.match({id: req.params.id})
.select() // not needed on 1.x libs
if (error || data.length === 0) {
res.status(400).send({...})
}

UnhandledPromiseRejectionWarning while using findOne() in NodeJs

I'm working on a project in which, at a moment, have to redirect the user if the id of a course does not exist.
This is the code:
router.get('/taller/:id', (req, res) => {
let tallerId = req.params.id;
Taller.findOne({_id: tallerId}).then(taller => {
if(taller) {
res.render('taller');
} else {
res.redirect('/dashboard');
}
});
});
The idea is that if the id passed in the params actually exists in the Talleres collection, the taller view is rendered. But, if it isn't, then the user should be redirected to the dashboard.
When the code with an invalid id runs I get:
UnhandledPromiseRejectionWarning: CastError: Cast to ObjectId failed for value "5c7d9da0567a653a40295bc}" at path "_id" for model "Taller"
Thanks in advance for any help.
Tom.
You did not define the catch block so the rejections i.e errors are not handled try below code
router.get('/taller/:id', (req, res) => {
let tallerId = req.params.id;
Taller.findOne({_id: tallerId}).then(taller => {
if(taller) {
res.render('taller');
} else {
res.redirect('/dashboard')
}
});
}).catch(err=>{console.log(err)});

Node.js shows [object Object] instead of result.row

I'm using postgresql version 11 and have a user with id=3 with a post field(text type). when I want to show the post from database it shows [object Object] instead of the post with id=3
const express = require('express');
const app = express();
const { Pool, Client } = require('pg')
const connectionString = 'postgresql://postgres:1111#localhost:5432/netSecure'
const pool = new Pool({
connectionString: connectionString,
})
app.get('/h', (req, res) => {
pool.query('SELECT post from users where id=3', (err, result) => {
if(err) return console.log('error in query',err);
console.log(result.rows);
res.render('posts.pug', {
post: result.rows
});
res.end();
});
app.listen(3000, () => console.log('http://localhost:3000'))
pug file with #{post}:
body
form(action='/posts',method='post')
label(for='exampleFormControlTextarea1') Enter Your Post
textarea(autofocus='', placeholder='Post your message here...')#exampleFormControlTextarea1.form-control(rows='3')
button(type="button").send Send
form(action='/logout',method='post')
button.logout Logout
p #{post}
Where did I make mistake?
[object Object] is the default toString representation of an object in javascript.
It seems that you only want to retrieve one post with id = 3. So first you need to extract one result because postgresql will give you an array of result no matter what.
And then, you need to process the JSON object so that it is not shown as [object Object]. For quick solution, you can use JSON.stringify()
So here is the snippet of your code
app.get('/h', (req, res) => {
pool.query('SELECT post from users where id=3', (err, result) => {
if(err) return console.log('error in query',err);
// need to check if post exists
let post = (result.rows.length > 0) ? result.rows[0] : null;
let postInString = JSON.stringify(post);
console.log(postInString);
res.render('posts.pug', {
post: postInString,
});
res.end();
});
The problem seems to be that you are trying to console.log something that is not in string format; this is why you are seeing [Object object].
To log what you actually want, consider first turning the object into a string with JSON.stringify(result.rows).

Mongoose update through $set a value if NOT undefined (NodeJS)

what's the proper way to check for undefined values? What I want to do is to have a PUT method that will update those fields that are not empty. For example, if I send req.body.name = 'John' and no req.body.job I want my request to only change the name.
Some code:
router.put('/:id', (req, res) => {
const query = {_id: req.params.id};
const update = {
$set: {
name: req.body.name,
job: req.body.job
}
};
User.findOneAndUpdate(query, update,
(err, userUpdated) => {
if (err) {
console.log('Error while updating');
console.log(err);
} else {
res.send(userUpdated);
}
});
});
This will of course throw an error:
CastError: Cast to number failed for value "undefined" at path "job"
Now I can manually check if req.body.job is empty and if it is set it's value to the value the user had previously, but that seems like a hack, not elegant and a lot of writing for each route.
I have checked the docs but none of the options provided there seem to do the job. I also came across something like express validator but this will probably just do a return if the value is empty. Another options would be to simply send the value from the front-end part.
I'm new to backend development and I'm not sure if I'm doing stuff the "right way". So please, any comment on how it should be done would be nice (also if my code looks odd, feel free to guide me :)), thanks!
You can write your own method to do this.
For example this example
var req = {body: {name: undefined, job: 'yes'}};
const _ = require('lodash');
const out = {};
_(req.body).forEach((value,key) => {
if (!_.isEmpty(value)){
out[key] = value;
}
});
console.log(out);
Is having this output
{ job: 'yes' }
You can also write it as middleware, if you want, if you write it as this
function onlyNotEmpty(req, res, next) => {
const out = {};
_(req.body).forEach((value, key) => {
if (!_.isEmpty(value)) {
out[key] = value;
}
});
req.bodyNotEmpty = out;
next();
}
Then you can write your method with middleware
router.put('/:id', onlyNotEmpty, (req, res) => {
const query = {_id: req.params.id};
const update = {
$set: req.bodyNotEmpty
};
// This will be the same
});

Resources