Express server GET request userId - node.js

I want to create an GET API route for taskuser/getallusers?userId='' .
I want to get all tasks that are assigned to a specific user. But when i test this call (http://localhost:4000/api/taskuser/getalltasks?userId=5bfe4af425ddde2b04eb19c6) but no error ?
I still get all tasks assigned to any user. can someone tell me what goes wrong ?
Model taskuser:
const mongoose = require('mongoose');
const TaskuserSchema = new mongoose.Schema({
task_name:{
type: String,
required: true,
minlength: 1,
unique: true,
},
userId: {
type: mongoose.Schema.Types.ObjectId,
required: true,
},
task_category: String,
task_xpreward: Number,
task_completed: Boolean,
task_difficulty: Number,
task_city : String,
});
Api route:
router.get('/getalltasks/:userid', cors(),async(req,res) => { // Add /:userid
var userid = req.params.userid;
Taskuser.find({ userId: userid}, function(err, tasks) {
// if there is an error retrieving, send the error.
// nothing after res.send(err) will execute
if (err)
res.send(err);
res.json(tasks); // return all tasks that are in JSON format
});
});
Edit: new api route

You should update the code to :
router.get('/getalltasks/:userid', cors(),async(req,res) => { // Add /:userid
var userid = req.params.userid;
Taskuser.find({ userId: userid}, function(err, tasks) {
// if there is an error retrieving, send the error.
// nothing after res.send(err) will execute
if (err)
res.send(err);
res.json(tasks); // return all tasks that are in JSON format
});
});
Documentation : https://mongoosejs.com/docs/api.html#model_Model.find

Change your api route file to this:
router.get("/getalltasks", cors(), async (req, res) => {
var userid = req.params.userId;
Taskuser.find({ userId: userid }, function(err, tasks) {
var userid = req.params.userId;
// if there is an error retrieving, send the error.
// nothing after res.send(err) will execute
if (err) res.send(err);
res.json(tasks); // return all tasks that are in JSON format
});
});

Related

Get data from findOne mongoose inside another findOne function

I am trying to get the candidate or HR (user roles) object using mongoose and nodejs. I have a user and both roles are derived from it.
when trying to connect using a UNIQUE username and a password. A user object will be sent as a result. I want to also send candidate/ or HR that are linked to that user.
I am passing the user object by reference to the candidate/HR schema:
const candidateSchema = new Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
index: true,
},
fullName: String,
profilePhoto: String,
birthday: Date,
I need to get the candidate object of the user that i get inside the exec() function. save it in a variable and send it as a res to signin function
app.post("/api/auth/signin", (req, res) => {
User.findOne({
username: req.body.username,
})
.populate("roles", "-__v")
.exec((err, user) => {
if (err) {
res.status(500).send({ message: err });
return;
}
const candi = candidat.findOne({ user: user }).exec((err, candidate) => {
//I want to save the candidate var
}));
//console.log("res",candi);
.....
});
A simple solution will be to wrap your code inside a promise and resolve whatever you want to store to variable while reject when you want to send error.
But its recommended to break down your code to multiple async functions and await them instead of using callback exec functions.
app.post("/api/auth/signin", async (req, res) => {
try{
let response = await new Promise((resolve,reject)=>{
User.findOne({
username: req.body.username,
})
.populate("roles", "-__v")
.exec((err, user) => {
if (err) {
//REJECT ERROR
reject(err);
return;
}
const candi = candidat.findOne({ user: user }).exec((err, candidate) => {
//RESOLVE YOUR CANDIDATE
resolve(canditate);
}));
//console.log("res",candi);
.....
});
.... your rest of code
})
res.send(response) // or required json
}catch(err){
res.status(500).send({ message: err });
}
}

Mongoose Update

I can't update the status field in the document. can somebody please help? Thanks!
changing the default value is the issue.
i want the admin to be able to update the status of the applicant from pending to whatever option is chosen from the select options in the ejs form
this is in the controller:
exports.postName = async(req, res, next)=>{
const name = req.body.name;
console.log(name)
const pupil = new Pupil({
name: name,
});
await pupil.save().then(updates=>{
console.log(updates)
res.redirect('/name');
}).catch(error=>{
console.log(error);
});
}
this also is from the controller:
exports.postUpdatePupil = async (req, res, next)=>{
const status = req.body.status
Pupil.updateOne(
{_id: req.params.id},
{
$set: {'Pupil.$.status': status}
},(err, result)=>{
if(err){
return next(err)
}console.log(result);
}
)
this is the model:
const UpdateSchema = new mongoose.Schema({
name: String,
status: {type: String, default: "Pending"}
});
const update = mongoose.model('update', UpdateSchema);
module.exports = update;
Model name should be "Pupil" and not "Update".
const PupilSchema = new mongoose.Schema({
name: String,
status: {type: String, default: "Pending"}
});
module.exports = mongoose.model('Pupil', PupilSchema);
And you update like:
Pupil.updateOne(
{ _id: req.params.id },
status // same as { status: status }
(err, result) => {
if (err) return next(err);
console.log(result);
},
);

Expressjs + Mongoose - This webpage is not available?

Why mongoose crashes the expressjs site?
Below is my code:
var express = require('express');
var mongoose = require('mongoose');
var app = express();
// Connect to mongodb
mongoose.connect("mongodb://localhost/testdb", function(err) {
if (err) throw err;
console.log("Successfully connected to mongodb");
// Start the application after the database connection is ready
app.listen(3000);
console.log("Listening on port 3000");
});
// With Mongoose, everything is derived from a Schema. Let's get a reference to it and define our users.
var userSchema = mongoose.Schema({
name: String,
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
admin: Boolean,
location: String,
meta: {
age: Number,
website: String
},
created_at: Date,
updated_at: Date
});
// The next step is compiling our schema into a Model.
var User = mongoose.model('User', userSchema);
// Set route.
app.get("/", function(req, res) {
// We can access all of the user documents through our User model.
User.find(function (err, users) {
if (err) return console.error(err);
console.log(users);
})
});
I get this on browser:
This webpage is not available
But in my terminal I get the result:
Successfully connected to mongodb
Listening on port 3000
[ { _id: 57682f69feaf405c51fdf144,
username: 'testuser1',
email: 'testuser1#testdomain.com' },
{ _id: 57683009feaf405c51fdf145,
username: 'testuser2',
email: 'testuser2#testdomain.com' },
{ _id: 57683009feaf405c51fdf146,
username: 'testuser3',
email: 'testuser3#testdomain.com' }]
Any ideas what I have missed?
The problem is that you are not writing anything in the response object in your request handler. Therefore the browser keeps waiting for the request to finish and ends up with a timeout. In your app.get(), you can update the response like this:
// Set route.
app.get("/", function(req, res) {
// We can access all of the user documents through our User model.
User.find(function (err, users) {
if (err) {
console.error(err);
// some simple error handling, maybe form a proper error object for response.
res.status(500).json(err);
}
console.log(users);
res.status(200).json(users); // setting the object as json response
//OR
// res.end(); if you don't want to send anything to the client
})
});
or something similar.
Refer the Express documentation for more details:http://expressjs.com/en/api.html#res

Mongoose - findByIdAndUpdate - doesn't work with req.body

I have a problem with update documents in mongodb over mongoose.
My model bellow:
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var UserSchema = new mongoose.Schema({
first_name:{
type: String
},
last_name:{
type: String
},
email:{
type: String,
unique: true,
required: true
},
password:{
type: String,
required: true
},
is_active:{
type: Boolean,
default: true
},
last_login:{
type: Date
}
});
module.exports = mongoose.model('User', UserSchema);
Controller put function bellow:
exports.updateUser = function (req, res) {
console.log(req.body);
User.findByIdAndUpdate(req.body.user_id, {$set:req.body}, function(err, result){
if(err){
console.log(err);
}
console.log("RESULT: " + result);
});
res.send('Done')
}
Output on console:
Listening on port 3000... { first_name: 'Michal', last_name: 'Test' }
PUT /api/users/54724d0fccf520000073b9e3 200 58.280 ms - 4
The printed params are provided as form-data (key-value). Looks that is not working at least for me any idea what is wrong here?
You have to use req.params.user_id instead req.body.user_id
exports.updateUser = function (req, res) {
console.log(req.body);
User.findByIdAndUpdate(req.params.user_id,{$set:req.body},{new:true}, function(err, result){
if(err){
console.log(err);
}
console.log("RESULT: " + result);
res.send('Done')
});
};
I found the mistake. Note that I'm calling
req.body.user_id
where should be
req.params.user_id
url is (PUT) http://127.0.0.1:3000/api/users/54724d0fccf520000073b9e3
Further, the req.body would have key value as Text and realized as String object, inside the code. Thus, it is useful to parse the string into JSON using JSON.parse(req.body.user) - while the user is the key and { first_name: 'Michal', last_name: 'Test' } is the value.
console.log(req.body);
var update = JSON.parse(req.body.user);
var id = req.params.user_id;
User.findByIdAndUpdate(id, update, function(err, result){
if(err){
console.log(err);
}
console.log("RESULT: " + result);
res.send('Done')
});
Note: the update value is sent to Mongo DB as
{$set: { first_name : 'Michal`, last_name: 'Test' }
Further reference: Mongoose JS documentation - findByIdAndUpdate

node.js email verification token

I'm trying to set up a verification step in Mongoose, Express Node application based on this blog post ... http://danielstudds.com/adding-verify-urls-to-an-express-js-app-to-confirm-user-emails-secure-spa-part-6/ that post is over a year old so it kind of surprises me that its the first google result for 'node email verification'. I'm very new to node so I'm reliant on examples. Based on that post I did not see a download so I pieced it together to suit my scenario and here is what my code looks like.
Verification Model
var mongoose = require('mongoose'),
uuid = require('node-uuid'),
User = require('mongoose').model('User');
var verificationTokenSchema = new mongoose.Schema({
_userid : { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
token: {type: String, required: true},
createdAt: {type: Date, required: true, default: Date.now, expires: '4h'}
});
verificationTokenSchema.methods = {
createVerificationToken : function (done) {
var verificationToken = this;
var token = uuid.v4();
verificationToken.set('token', token);
verificationToken.save( function (err) {
if (err) return done(err);
return done(null, token);
});
}
};
exports.verifyUser = function(token, done) {
verificationTokenModel.findOne({token: token}, function (err, doc){
if (err) return done(err);
User.findOne({_id: doc._userId}, function (err, user) {
if (err) return done(err);
user["verified"] = true;
user.save(function(err) {
done(err);
});
});
});
};
var verificationTokenModel = mongoose.model('VerificationToken', verificationTokenSchema);
exports.verificationTokenModel = verificationTokenModel;
Then in my User model I call create like so..
User Model
exports.createUser = function(req, res, next) {
// Do all the stuff that creates the user save it and get the id back
var verificationToken = new verificationTokenModel({_userId: user._id});
verificationToken.createVerificationToken(function (err, token) {
if (err){
err = new Error("Couldn't create verification token");
res.status(400);
return res.send({reason:err.toString()});
}
// Do stuff with the token here and email
This works 'partially' in my db 'verificationtokens' collection the objects don't contain a _userid they contain the _userid (user._id) stored in _id
My first issue is I don't really understand how this works when there isn't a 'constructor'
var verificationToken = new verificationTokenModel({_userId: user._id});
and how do I get this to store the user._id as _userid in the verification collection
I don't use Mongoose, but here is what it happened:
For your first question:
when you run:
var verificationTokenModel = mongoose.model('VerificationToken', verificationTokenSchema);
it creates the constructor.
For the second question:
MongoDB always create documents with a field called "_id", so, the "_id" field in your verification collection is not the "_id" field from your User collection. The reason that _userid is not inserted is because you have a typo:
var verificationToken = new verificationTokenModel({_userId: user._id});
where "_userId" should be "userid"

Resources