Is there a way to convert this pg.Pool query to Knex? - javascript

I am trying to convert my pg pool queries to Knex and am having an issue with this query:
router.post('/register', validInfo, async (req, res, next) => {
const { email, name, password } = req.body;
try {
const user = await pool.query('SELECT * FROM users WHERE user_email = $1', [email]);
res.json(user);
} catch (err) {
console.error(err);
}
});
Here is what I have so far:
router.post('/register', validInfo, async (req, res, next) => {
const { email, name, password } = req.body;
try {
//Check if user exists
const user = await knex('users')
.select('*')
.where('user_email', $1, [email]);
res.json(user);
} catch (err) {
console.error(err);
}
});
When I create a new user in Postman I should receive an empty array but it's not working. What needs to change in order to match the first query?

Related

API POST request getting Error: Cannot read properties of undefined (reading 'job_title')

I have built and API with Express to POST a new job in a project I am currently working on. The GET requests work fine, also the DEL, but the POST one is not working. I am connected to a POSTGRES database.
I have defined the following path for the API:
app.use('/api/jobs', jobRoutes);
so when I send a POST request like below:
localhost:4000/api/jobs/createjob
it should work. What is also weird, is that the code was working perfectly before, but now I can't seem to figure it out anymore. I tried looking elsewhere, but I couldn't find any solution when getting this kind of error with APIs.
My API looks like the following:
router.post("/createjob", async (req, res) => {
try {
const {job} = req.body;
const newJob = await pool.query("INSERT INTO job(job_title, job_department, country_id, description, expiration_date) VALUES($1, $2, $3, $4, $5) RETURNING *", [job.job_title, job.job_department, job.country_id, job.description, job.expiration_date]);
res.json(newJob.rows);
} catch (error) {
console.error(error.message);
}
})
I am making the POST request with Postman, and the body looks like this:
{
"description": "job_description",
"job_title": "Back End Developer"
}
When I send the requests, in the terminal shows this error:
Cannot read properties of undefined (reading 'job_title')
Full code of the Routes:
const express = require("express");
const router = express.Router();
const pool = require("../db");
// routes
// get all jobs
router.get('/alljobs', async (req, res) => {
try {
const allJobs = await pool.query("SELECT * FROM job");
res.json(allJobs.rows)
} catch (error) {
console.error(error.message);
}
})
// GET a single job
router.get('/job/:id', async (req, res) => {
try {
const {id} = req.params;
const job = await pool.query("SELECT * FROM job WHERE job_id = $1 ", [id]);
res.json(job.rows)
} catch (error) {
console.error(error.message);
}
})
// create a job
router.post("/createjob", async (req, res) => {
try {
const {job} = req.body;
const newJob = await pool.query("INSERT INTO job(job_title, job_department, country_id, description, expiration_date) VALUES($1, $2, $3, $4, $5) RETURNING *", [job.job_title, job.job_department, job.country_id, job.description, job.expiration_date]);
res.json(newJob.rows);
} catch (error) {
console.error(error.message);
}
})
// update a job
router.patch("/updatejob/:id", async (req, res) => {
try {
const {id} = req.params;
const {description} = req.body;
const updateJob = await pool.query("UPDATE job SET description = $1 WHERE job_id = $2", [description, id]);
res.json(updateJob.rows);
} catch (error) {
console.error(error.message);
}
})
// delete a job
router.delete("/deletejob/:id", async (req, res) => {
try {
const {id} = req.params;
const deleteJob = await pool.query("DELETE FROM job WHERE job_id = $1", [id]);
res.json(deleteJob.rows);
} catch (error) {
console.error(error.message);
}
})
// get all countries
router.get("/countries", async (req, res) => {
try {
const allCountries = await pool.query("SELECT * FROM countries");
res.json(allCountries.rows)
} catch (error) {
console.error(error.message);
}
})
// //create new user
// router.post("/newuser", async (req, res) => {
// try {
// const {user} = req.body;
// const newUser = await pool.query("INSERT INTO users(user_name, email, password, is_candidate, is_recruiter) VALUES($1, $2, $3, $4, $5) RETURNING *", [user.user_name, user.email, user.password, user.candidate, user.recruiter]);
// res.json(newUser.rows);
// } catch (error) {
// console.error(error.message);
// }
// })
module.exports = router;
Full code of my server.js file:
const express = require("express");
const router = require("./routes/jobRoutes");
const jobRoutes = require("./routes/jobRoutes");
const cors = require("cors");
//creates express app
const app = express();
app.use(express.json());
app.use(cors());
//middleware
app.use((req,res,next) => {
console.log("req.path", req.method);
next();
})
app.get("/status", (req, res, next) => {
res.send("connected");
});
// for every other request
app.use('/api/jobs', jobRoutes);
// more middleware
app.use((err, req, res, next) => {
let status = err.status || 500;
let message = err.message;
console.error(err);
return res.status(status).json({
error: { message, status },
});
});
//listen for requests
app.listen(4000, () => {
console.log("listening on port 4000")
});
I tried looking elsewhere, but I couldn't find any solution when getting this kind of error with APIs. The GET and the DEL requests work as expected.

.findbycredentials no response

My problem is when I make a request to POST /users/login with true data I receive no response instead the catch throw 400
routs file :
const express = require("express");
const router = new express.Router();
const User = require("../models/user");
router.post("/users/login", async (req, res) => {
try {
const user = await User.findByCredentials(
req.body.email,
req.body.password
);
// console.log(user);
res.send({ user });
} catch (e) {
res.status(400).send();
}
});
module.exports = router;
user middleware
userSchema.static.findByCredentials = async (email, password) => {
const user = await User.findOne({ email: email });
if (!user) {
throw new Error("Unable to find the user");
}
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) {
throw new Error("uncorect password");
}
return user;
};
Not all the code here, but I am sure the problem is in these lines,
In user middleware it should be statics(plural)
userSchema.statics.findByCredentials = async (email, password) => {
})

Data and salt arguments required error (authorization)

I'm a beginner in NodeJS and I've tried to make an authentication form using NodeJS + express. I want to make a validation for my password (when "confirmpassword" is different than "password" it should return nothing. Unfortunately, I keep getting "data and salt arguments required". I tried in different ways, to put some conditions, but I keep getting this error. Any ideas how I should make it work?
Here is the file user.js:
const pool = require('./pool');
const bcrypt = require('bcrypt');
function User() {};
User.prototype = {
find : function(user = null, callback)
{
if(user) {
var field = Number.isInteger(user) ? 'id' : 'username';
}
let sql = `SELECT * FROM users WHERE ${field} = ?`;
pool.query(sql, user, function(err, result) {
if(err)
throw err
if(result.length) {
callback(result[0]);
}else {
callback(null);
}
});
},
create : function(body, callback)
{
var pwd = body.password;
var cpwd = body.confirmpassword;
// here i hash the pass
body.password = bcrypt.hashSync(pwd,10);
body.confirmpassword = bcrypt.hashSync(cpwd, 10);
if (body.password != body.confirmpassword){
callback(null);
}
else {
var bind = [];
for(prop in body){
bind.push(body[prop]);
}
let sql = `INSERT INTO users(username, fullname, password) VALUES (?, ?, ?)`;
pool.query(sql, bind, function(err, result) {
if(err) throw err;
callback(result.insertId);
});
}
},
login : function(username, password, callback)
{
this.find(username, function(user) {
if(user) {
if(bcrypt.compareSync(password, user.password)) {
callback(user);
return;
}
}
callback(null);
});
}
}
module.exports = User;
And the file pages.js:
const express = require('express');
const User = require('../core/user');
const router = express.Router();
const user = new User();
router.get('/', (req, res, next) => {
let user = req.session.user;
if(user) {
res.redirect('/home');
return;
}
res.render('index', {title:"My application"});
})
router.get('/home', (req, res, next) => {
let user = req.session.user;
if(user) {
res.render('home', {opp:req.session.opp, name:user.fullname});
return;
}
res.redirect('/');
});
router.post('/login', (req, res, next) => {
user.login(req.body.username, req.body.password, function(result) {
if(result) {
req.session.user = result;
req.session.opp = 1;
res.redirect('/home');
}else {
res.send('Username/Password incorrect!');
}
})
});
router.post('/register', (req, res, next) => {
let userInput = {
username: req.body.username,
fullname: req.body.fullname,
password: req.body.password
};
user.create(userInput, function(lastId) {
if(lastId) {
user.find(lastId, function(result) {
req.session.user = result;
req.session.opp = 1;
res.redirect('/home');
});
}else {
console.log('Error creating a new user ...');
}
});
});
router.get('/logout', (req, res, next) => {
if(req.session.user) {
req.session.destroy(function() {
res.redirect('/');
});
}
});
module.exports = router;
In userInput, you are not passing confirmpassword property.
let userInput = {
username: req.body.username,
fullname: req.body.fullname,
password: req.body.password
};
In create method, you are accessing it.
var cpwd = body.confirmpassword;
cpwd is null, and that's the reason for the error.
body.confirmpassword = bcrypt.hashSync(cpwd, 10);//**cpwd is null**
As per the docs, data is required argument and this cannot be null.
hashSync(data, salt)
data - [REQUIRED] - the data to be encrypted.
salt - [REQUIRED] - the salt to be used to hash the password.

Return multiple rows from database in node

I am trying to return all the details of the product and display them in table format
I have already tried this in my api
app.get('/test',(req,res) => {
const client = new Client({
connectionString: connectionString
})
client.connect()
client.query('select * from product',(err,res) =>{
console.log(err,res)
if(err){
console.log(err);
}else{
console.log(res);
}
client.end()
})})
How do i return this res in node?
You are hiding the outside res in the route handler with the inside res of the query result.
I have to make some assumptions about your query client, but if the inside res is the array of rows, simply pass it to the res.json() function (another assumption is you are using Express).
My suggestion:
app.get('/test', (req, res) => {
const client = new Client({
connectionString: connectionString
})
client.connect()
client.query('select * from product', (err, rows) => {
console.log(err, rows)
if (err) {
console.log(err);
} else {
console.log(rows);
res.json(rows);
}
client.end()
})
});

Update user information

Tried this for updating user information , only phone number but it's not getting update.
router.post('/edit', checkAuth, function (req, res, next) {
console.log(req.userData.userId)
User.update({_id: req.userData.userId}, {$set:req.userData.phoneNo}, function (err){
if (err) {
console.log(err);
}
res.status(200).send(req.userData);
});
});
My user controller const mongoose = require ('mongoose');
const User = mongoose.model('User');
module.exports.register = (req, res, next) =>{
var user = new User();
user.fullName = req.body.fullName;
user.email = req.body.email;
user.password = req.body.password;
user.phoneNumber = req.body.phoneNumber;
user.save((err, doc) =>{
if(!err)
res.send(doc);
else{
if (err.code == 11000)
res.status(422).send(["Entered duplicate email address. Please check"]);
else
return next(err);
}
});
}
And then I am authenticating by passing jwt on this field
phoneNo: user[0].phoneNumber
The auth-token verifies and decode the fields
const token = req.headers.authorization.split(" ")[1];
const decoded = jwt.verify(token, process.env.JWT_KEY)
req.userData = decoded;
Update is not working and getting error message Invalid atomic update value for $set. Expected an object, received string .
first of all, you should use PATCH-method - because you are updating only one item in existed object, in body you should send id of user and new value of certain value. If you use mongoose you can try it
User.findOneAndUpdate({ _id: id }, updatedItem, { new: true }, (err, doc) => {
if (err) return res.send(err.message)
if (doc) return res.send(doc);
})
const id = req.body._id;, if you dont use mongoose you should try findAndModify method
Your code
User.update({_id: req.userData.userId}, {$set:req.userData.phoneNo}
Correct code:
User.update({_id: req.userData.userId}, {$set:{phoneNumber:req.userData.phoneNo}}
Try this method:
User.findByIdAndUpdate(req.userData.userId, { $set:{phoneNumber:req.userData.phoneNo}}, { new: true }, function (err, user) {
if (err) console.log(err);
res.send(user);
});

Categories