Why am I getting, "Undefined binding(s) detected when compiling FIRST."? - javascript

I have an app with 3 routes: register, login, and dashboard; with dashboard being a protected route.
Within my dashboard route, I am creating a post request which will retrieve the users information.
In my service file:
//Return a user by ID
const getUserById = (id) =>
knex('users').select('user_name').where({ user_id: id }).first();
In my controller file:
async function create(req, res, next) {
try {
const user = await service.getUserById(req.user);
res.json(user);
} catch (err) {
console.error(err.message);
}
}
I get this error:
Undefined binding(s) detected when compiling FIRST. Undefined column(s): [user_id] query: select "user_name" from "users" where "user_id" = ? limit ?
My table users has 4 columns: user_id, user_name, user_email, and user_password.
What is wrong with my service file or controller file?

Looking from code the req.user must be undefined.

You are passing a user object to the function when it expects an id.
service.getUserById(req.user)
But the function signature is:
const getUserById = (id) => ...

Related

Node.js getting Uncaught error: invalid input syntax for type integer: "NaN"

I am very new to JS and I'm trying to create an API using node.js however I'm getting the error:
Uncaught error: invalid input syntax for type integer: "NaN"
The requests are fine when I do a GET and POST request but I'm having trouble with the PUT and DELETE. I get the same error with both requests. Here is my code:
const getProfiles = (request, response) => {
pool.query('SELECT * FROM profiles', (error, results) => {
if (error) {
throw error
}
response.status(200).json(results.rows)
})
}
const addProfiles = (request, response) => {
const {name, bio} = request.body
pool.query(
'INSERT INTO profiles (name, bio) VALUES ($1, $2) RETURNING id',
[name, bio],
(error) => {
if (error) {
throw error
}
response.status(201).json({status: 'success', message: 'Profile added.'})
})
}
const updateProfiles = (request, response) => {
const id = parseInt(request.params.id)
const {name, bio} = request.body
pool.query(
'UPDATE profiles SET name = $1, bio = $2 WHERE id = $3 RETURNING id',
[name, bio, id],
(error) => {
if (error) {
throw error
}
response.status(202).json({status: 'success', message: 'Profile updated with ID: ${id}'})
})
}
const deleteProfiles = (request, response) => {
const id = parseInt(request.params.id)
pool.query(
'DELETE FROM profiles WHERE id = $1', [id],
(error, results) => {
if (error) {
throw error
}
response.status(203).send(`Profile deleted with ID: ${id}`)
})
}
app
.route('/profiles')
// GET endpoint
.get(getProfiles)
// POST endpoint
.post(addProfiles)
//UPDATE endpoint
.put(updateProfiles)
// DELETE endpoint
.delete(deleteProfiles)
// Start server
app.listen(process.env.PORT || 3002, () => {
console.log(`Server listening`)
})
I am very much new to this and if you spot where I went wrong I would very much appreciate and explanation for me to better understand it and never make this mistake again. Thank you.
As far as I can see, req.params.id is undefined, because you are not telling express that route should receive a param.
Change this:
app
.route('/profiles')
// GET endpoint
.get(getProfiles)
// POST endpoint
.post(addProfiles)
//UPDATE endpoint
.put(updateProfiles)
// DELETE endpoint
.delete(deleteProfiles)
To this:
app
.route('/profiles')
// GET endpoint
.get(getProfiles)
// POST endpoint
.post(addProfiles)
app
.route('/profiles/:id') // :id means we are expecting that param
//UPDATE endpoint
.put(updateProfiles)
// DELETE endpoint
.delete(deleteProfiles)
And when you do the PUT or DELETE request, the endpoint should look like this: /profiles/
The error means you'r providing a "Not a Number" (NaN) where your app expects a number (integer).
It's most probably the id in the updateProfiles or deleteProfiles, because you haven't defined it your route
app
.route('/profiles/:id')
// GET endpoint
.get(getProfiles)
// POST endpoint
.post(addProfiles)
//UPDATE endpoint
.put(updateProfiles)
// DELETE endpoint
.delete(deleteProfiles)

Retrieve Authenticate User's Orders

GET method
Use accessToken of an authenticated user.
Only non-admin account can proceed.
User should be able to retrieve his orders only.
Router
router.get("/my-orders", auth.verify, (req, res) => {
const user = auth.decode(req.headers.authorization);
if (!user.isAdmin) {
UserController.getMyOrders(req.body).then(getMine => res.send(getMine));
} else {
return res.status(403).send("Access denied.");
}
});```
Controller
module.exports.getMyOrders = (body) => {
return User.find({}, {
"isAdmin": 0,
"_id": 0,
"password": 0
});
}
I am getting everything. Can someone help me code how to filter the user where the token belongs and retrieve his orders and not able to get other users' orders?
By passing an empty object in your .find method, you are telling mongodb to look for everything. I'm assuming in body you have some data to find a specific user, if so you would use that. eg. if body contains a username, you would write...
module.exports.getMyOrders = (body) => {
return User.find({username: body.username});
}
Here is some more info on db.collection.find()
EDIT - Look up user by JWT:
router.get("/my-orders", auth.verify, (req, res) => {
//Here you have decoded your JWT and saved it as user
const user = auth.decode(req.headers.authorization);
if (!user.isAdmin) {
//here you are passing user instead of req.body
UserController.getMyOrders(user).then(getMine => res.send(getMine));
} else {
return res.status(403).send("Access denied.");
}
});
module.exports.getMyOrders = (user) => {
//now you are using 'username' from the decoded jwt to look up the user
return User.find({username: user.username});
}

Mongoose await for node.js req.query data

I am working on small backend project. I send GET requests via postman to express.js app. Express send request to mongoose and return data.
I am trying to make it shorter by writing req.query.data instead of object name.
req.query.data is object name which is imported to node file but mongoose "find" function read it as "req.query.data" instead of acuall data.
I tried putting req data in () but it still didn't want to read value. I have no idea how to make it working
Code:
const Daily = require("./DailyStats/DailySchema")
module.exports.GetData = async (req, res) => {
await Daily.find({"Date.month": 3}, function (err, data) {
if(err){
console.error(err)
}
res.send(data)
})
}
What I want is
await (req.query.data).find({"Date.month": 3}, function (err, data) {
if(err){
console.error(err)
}
res.send(data)
})
While using second code I got error "Cannot use method find on req.query.data"
find should be called on a mongoose.Model
You may use mongoose.model(req.query.data) assuming req.query.data is your model name
That said you should
check that provided data is only a valid model name
name data better, like modelName
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/dummy')
const NameModel = mongoose.model('Name', { name:String }, 'names')
;(async()=>{
try {
console.log(mongoose.model('Name') === NameModel) // true
} finally {
mongoose.disconnect()
}
})()

How to send get http request with httpParams from angular to nodejs api

I want to send a http request to get some filtered data from a Complaint model, from angular app to nodejs api.
angular :
getFiletredComplaints() {
const params = new HttpParams()
.set('status', this.chosenStatus)
.set('type', this.chosenType)
this.http.get("/api/complaints/filteredComplaints", { params }).subscribe((data: any) => {
console.log(data)
});
}
node :
export default function (router) {
router.get('/complaints/filteredComplaints', isAdmin, isLoggedIn, filterComplaints) // no doc writed
}
export async function filterComplaints(req, res) {
console.log(req.query.params);
try
var data = {
sampleTime: '1450632410296',
data: '76.36731:3.4651554:0.5665419'
}
return res.json(data)
} catch (error) {
return res.status(500).end()
}
}
I'm trying to read and test if my params sent successfully but I got this error :
error "Cast to ObjectId failed for value \"{ _id: 'filteredComplaints'
}\" at path \"_id\" for model \"Complaint\""

ReactJS + Redux: Why isn't MongoDB saving data to the database even with correct API requests?

I have a MongoDB/Webpack/NodeJS Express set up in my ReactJS + Redux project.
I am making API calls from action creators in redux, and reach the API server and get a successful status back, yet the data never gets saved and the database never gets created even checking with in terminal mongo -> dbs and it doesn't show practicedb database which I named it as.
What could be the issue? Am I missing something?
Any guidance or insight would be greatly appreciated. Thank you
This is my set up for API:
import axios from 'axios';
import { browserHistory } from 'react-router';
import cookie from 'react-cookie';
import { AUTH_USER, AUTH_ERROR } from './types';
const API_URL = 'http://localhost:3000/api';
export function errorHandler(dispatch, error, type) {
let errorMessage = (error.data.error) ? error.data.error : error.data;
// NOT AUTHENTICATED ERROR
if(error.status === 401) {
errorMessage = 'You are not authorized to do this.';
}
dispatch({
type: type,
payload: errorMessage
});
}
export function registerUser({ email }) {
return function(dispatch) {
axios.post(`${API_URL}/auth/register`, { email })
.then(response => {
console.log('THIS IS TESTING PURPOSE')
console.log(response)
dispatch({ type: AUTH_USER });
})
.catch((error) => {
errorHandler(dispatch, error.response, AUTH_ERROR)
});
}
}
And my API controller is set up as such:
"use strict";
const User = require('../models/user')
exports.register = function(req, res, next) {
const email = req.body.email;
console.log('ERROR 1')
if(!email) {
return res.status(422).send({ error: 'You must enter an email address.'})
console.log('ERROR 1')
}
User.findOne({ email: email }, function(err, existingUser) {
if(err) { return next(err); }
console.log('ERROR 2')
if(existingUser) {
return res.status(422).send({ error: 'That email address is already in use.'})
}
console.log('ERROR 3')
let user = new User({
email: email,
})
console.log('ERROR 4')
user.save(function(err, user) {
if(err) { return next(err); }
console.log('ERROR 5')
res.status(201).json({
user: user,
})
})
})
console.log('ERROR 6')
}
Configuration for the API:
module.exports = {
'database': 'mongodb://localhost/practicedb',
'port': process.env.PORT || 3000,
'secret': 'dogcat',
}
The project so far just has an input text field, where it accepts an email address. If the email has already been registered, the API should return the error That email address is already in use. and it does.
So I tried console logging to see what the problem is, and the first time I submit the POST request, it logs the following (the terminal showing API console logs):
And if I try to submit the same email again, it throws me the API error that the email is already in use with 422 error, yet the data do not get saved and database (practicedb) never get created:
Also, what is the OPTIONS request that shows up in terminal? I only made an attempt to POST. Lastly, is OPTIONS why the ERROR log in API server is not logging in chronological order?
EDIT
You're using the wrong Mongo shell command: db will only show you the current database (test), but if you want to see a list of all databases, you should use show dbs.
If you want to switch databases:
use practicedb
And, if you want to see the collections in the current database:
show collections

Categories

Resources