I was developing a backend with a SQLite3 and I deployed to heroku with postgresQL, the databse worked fine when it was in development, everything worked as expected and now I'm getting an error stating
2019-02-22T11:51:48.768183+00:00 app[web.1]: error Error: Undefined
binding(s) detected when compiling FIRST query: select * from "users"
where "id" = ? limit ?
2019-02-22T11:51:48.768200+00:00 app[web.1]: at QueryCompiler_PG.toSQL
(/app/node_modules/knex/lib/query/compiler.js:85:13)
However, there are no undefined bindings
My schema looks like
exports.up = function (knex, Promise) {
return knex.schema.createTable('users', users => {
users.increments('id')
users.string('name').notNullable();
users.string('email').notNullable();
users.string('username').notNullable();
users.string('password').notNullable();
users.string('role').notNullable();
})
};
The Query looks like
router.post('/signup', (req, res) => {
const user = req.body;
const hashedPass = bcrypt.hashSync(user.password, 12)
user.password = hashedPass;
var username = user.username
db.insertUser(user)
.then(ids => {
const id = ids[0];
db.findByID(id)
.then(user => {
const token = (newToken(user));
res.status(200).json({ id: user.id,
username:username,token:token});
})
.catch(err => {
console.log("error", err);
res.status(500).json({ error: 'Something went wrong' })
})
})
.catch(err => {
res.status(500).send(err);
});
});
Lastly, the helper function is...
findByID: (id) => {
return db('users').where('id', id).first();
}
Do you know what would be causing such an error, I have tried to search for it on here, and Google and can't find it. Thank you much in advance!
Related
I'm currently part of a web dev Bootcamp and my current project is requesting I create error handlers in a specific manner that I do not understand. Below is a screenshot of the directions . . .
Here are my current files in hopes that it makes sense . . .
/* app.js */
const express = require('express');
const mongoose = require('mongoose');
const userRouter = require('./routes/users');
const cardRouter = require('./routes/cards');
const { PORT = 3000 } = process.env;
const app = express();
mongoose.connect('mongodb://localhost:27017/aroundb', {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
useUnifiedTopology: true,
});
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use((req, res, next) => {
req.user = { _id: '60c4e0e2a80be4c8c2de5474' };
next();
});
app.use('/users', userRouter);
app.use('/cards', cardRouter);
app.listen(PORT, () => logMsg(`listening on port ${PORT} . . .`));
/* routes/users.js */
const express = require('express');
const { getUsers, getUser, createUser } = require('../controllers/users');
const router = express.Router();
router.get('/', getUsers);
router.get('/:id', getUser);
router.post('/', createUser);
module.exports = router;
/* controllers/users.js */
const User = require('../models/user');
module.exports.getUsers = (req, res) => {
User.find({})
.then((users) => res.status(200).send({ data: users }))
.catch((err) => res.status(500).send({ message: err }));
};
module.exports.getUser = (req, res, next) => {
User.findById(req.params.id)
.then((user) => res.send({ data: user }))
.catch((err) => res.status(404).send({ message: err }));
};
module.exports.createUser = (req, res) => {
const { name, about, avatar } = req.body;
User.create({ name, about, avatar })
.then((user) => res.status(201).send({ data: user }))
.catch((err) => res.status(400).send({ message: err }));
};
My questions are:
Where should the code example provided (in the screenshot) go? Am I creating a separate controller or middleware? Or maybe it goes in the already coded controller?
Would I be creating my own errors and using a conditional to read the message?
I already thought I was handling errors, as seen in controllers/users.js, is that not the case?
NOTE: My apologies, I know that since it's from a course it might not make sense outside the context of the lesson(s). I also know there are various ways projects can be coded/solved. Unfortunately, my Bootcamp does not have live instruction, just a slack channel where 97% of responses come from Alumni. Please do not hesitate to ask questions that may help clarify things.
It seems you're directly sending an error in the last two cases, without knowing which type of it is, however it looks fine for fetching all users (1st case).
The workaround that might help you is,
Get user :
User.findById(req.params.id), function(err, user) {
if(err) {
return res.status(500).send({ message: "Default error" });
} else if (!user) {
return res.status(404).send({ message: "User not found" });
}
}
For creating a user you need to manually verify all the fields that are required in schema for ex.,
createUsers : {
const { name, about, avatar } = req.body;
if (name === null || about === null || avatar === null) {
return res.status(400).send({
message : "Required data missing in request"
})
}
... // create user
}
I want to create a static function on a mongoose "log" module, which would allow me to write a message as a log entry.
How do I access the model from within the static function? Can I use this.model like below? I don't want to simply use native MongoDB insert command, because I want the model to validate the input, etc.
// ... schema defined above...
var Log = mongoose.model('Log', LogModelSchema)
Log.statics.log = function(message) {
var x = new this.model({message: message})
x.save()
.then(() => { .. do something .. }
.catch((err) => { .. handle err .. }
}
Is this the way it's supposed to be done?
You can make it work like this using this.create:
const mongoose = require("mongoose");
const logSchema = new mongoose.Schema({
message: String
});
logSchema.statics.log = function(message) {
this.create({ message: message })
.then(doc => console.log(doc))
.catch(err => console.log(err));
};
module.exports = mongoose.model("Log", logSchema);
Now you can use this in your routes like this:
Log.log("test");
or just return promise from statics:
logSchema.statics.log = function(message) {
return this.create({ message: message });
};
And use like this:
const Log = require("../models/log");
router.get("/log", (req, res) => {
Log.log("test")
.then(result => {
console.log(result);
res.send("ok");
})
.catch(err => {
console.log(err);
res.status(500).send("not ok");
});
});
I'm trying to verify an apiKey which is passed into the url as a parameter. I am then checking that this apiKey is in the database by doing a Model.find({}) with mongoose. I then have a callback function using key as a parameter which I would expect to be null if the apiKey isnt in the database.
Unfortunately all I am getting is an empty value, which prints nothing to the console:
See code below but my console logs this, see how the key value being returned by mongoose is empty, not null.
key:
current: null
error: null
coffeeRouter.get('/', (req, res) => {
const currentUser = req.user;
const incomingApiKey = req.query['apiKey'];
console.log('Body: ' + incomingApiKey);
User.find({ apiKey: incomingApiKey }, function(err, key) {
console.log('key: ' + key);
console.log('current: ' + currentUser);
console.log('error: ' + err)
if((incomingApiKey === undefined || !key) && !currentUser) {
console.log('unauthenticated');
res.render('display.hbs', {currentUser});
} else {
Coffee.find({})
.then(coffees => {
console.log('authenticated');
console.log(coffees)
res.render('display.hbs', { coffees, currentUser });
})
.catch(err => {
console.log(err.message);
});
}
}).catch(err => {
console.log(err);
})
});
I'm writing an a async function with ES6 promises, that 1) saves the query parameters for a user 2) fetches data from mongodb using mongoose, 3) manipulates the json into a DSL, 4) and queries another db with it.
mongoose": "^4.7.7"
//myController.js
const myQuery = require('../models/myQuery_model');
require('mongoose').Promise = global.Promise
const uuidV4 = require('uuid/v4');
exports.saveNewQuery = function(req, res, next) {
const rawQuery = req.body;
const queryToStore = new myQuery(rawQuery);
const uid = uuidV4();
const queryToStore.uid = uid
queryToStore.save().then(() => {
fetchQueryFromMongo(uid);
}).then((storedQuery) => {
compileQueryToString(storedQuery);
}).then((queryString) => {
fetchResultsFromOtherDb(queryString);
}).then((results) => {
res.json({ results });
}).catch((error) => {
console.log(error)
})
}
Currently I'm not able to resolve the response from mongodb step 2. Still, the controllter goes on to compileQueryToString rather than catch the error from fetchQueryFromMongo
// fetchQueryFromMongo.js
const myQuery = require('../models/myQuery');
require('mongoose').Promise = global.Promise
module.exports = (uid) => {
return new Promise(
(resolve, reject) => {
myQuery.find({ uid }).then((err, res) => {
if (err) {
reject(err);
}
console.log('response success!')
resolve(res);
});
}
);
};
I'm new to promises so any tips / suggestions would be appreciated!
Make sure to return a value from your then handlers. The code below does this by using the concise body form of arrow functions.
queryToStore.save()
.then(() => fetchQueryFromMongo(uid))
.then(storedQuery => compileQueryToString(storedQuery))
.then(queryString => fetchResultsFromOtherDb(queryString))
.then(results => res.json({ results }))
.catch(console.log);
Meteor.methods({
'sync.toggl'(apiToken) {
const toggl = new TogglApi({ apiToken });
Promise.promisifyAll(toggl);
toggl.getWorkspacesAsync()
.each(ws => toggl.getWorkspaceProjectsAsync(ws.id)
.map(p => {
Projects.upsert({ projectId: p.id }, {
projectId: p.id,
name: p.name,
tracker: 'toggl',
tags: [],
contributors: []
});
})
.catch(err => console.error(`fetching ${ws.name} projects error - ${err.message}`));
)
.catch(err => console.error(`fetching ${ws.name} workspace error - ${err.message}`));
}});
I'm trying to save data from toggl api into local db here. But Meteor throws an error - Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment. I found couple solutions, but they doesn't allow me to use bluebird promises... or not?
Using async/await worked for me:
Meteor.methods({
'sync.toggl'(apiToken) {
const toggl = new TogglApi({ apiToken });
Promise.promisifyAll(toggl);
async function saveProject(pid, name) {
try {
return await Projects.upsert(
{ pid },
{
pid,
name,
tracker: 'toggl',
contributors: [],
}
)
} catch (err) {
return console.error(`async saveProject failed - ${err.message}`);
}
}
toggl.getWorkspacesAsync()
.each(ws => toggl.getWorkspaceProjectsAsync(ws.id)
.map(p => {
saveProject(p.id, p.name);
})
.catch(err => console.error(`fetching projects error - ${err.message}`))
)
.catch(err => console.error(`fetching workspaces error - ${err.message}`))
}});