0

I'm new to node js / Express development. I have developed a login service that works fine. Now i need to upgrade this service and using the username of login to do a query on other mongo document and retrieve an array result into json message I have write a query using findOne, and works, but if i use query find the array is empty

router.post('/login', function(req, res) {
User.findOne({ username: req.body.username}, function(err, user) {
    if (err){
        return res.status(500).send('Error on the server.');
    }
    if (!user){
        return res.status(401).send({status: 'ko', error: {msg: 'The username ' + req.body.username + ' is not associated with any account.'}});
    }
    var passwordIsValid = bcrypt.compareSync(req.body.password, user.password);
    //if (!passwordIsValid) return res.status(401).send({ auth: false, token: null });
    if (!passwordIsValid){
        return res.status(401).send({status: 'ko', error: {msg:'Authentication failed. Wrong password.',auth: false, token: null}});
    }
    // Make sure the user has been verified
    if (!user.isVerified){
        return res.status(401).send({status: 'ko', error: {type: 'not-verified', msg: 'Your account has not been verified.'}});
    }
    if (!user.statusUser){
        return res.status(401).send({status: 'ko', error: {msg: 'The username ' + req.body.username + ' is blocked by Admin'}});
    }
    // if user is found and password is valid
    // create a token
    var token = jwt.sign({ id: user._id }, config.secret, {
      expiresIn: 86400 // expires in 24 hours
    });

    // inserimento farm id //
    Farm.find({ farmId: user.farmId}, (err, farms) => {
        console.log(Farm.find({farmId:user.farmId}));
        var identify_farm = [];
        if (err) {
            //return res.status(400).send({ status: 'ko', data: {msg: err.message }});
            var txt = err.message;
            identify_farm.push(txt);
        }
        if (!farms) {
            //return res.status(404).send({ status: 'ko', data: {msg: 'Farm not found.'}});
            identify_farm.push('Farm not found.');
        }
        if (farms) {
            identify_farm.push(farms._id);
        }
    // inserimento farm id //

    // return the information including token as JSON
    req.session.user = user;
    res.status(200).send({status: 'ok', data: {auth: true, token: token, farmId: user.farmId, roles: user.roles, id_utente: user._id, identify_farms: identify_farm}});
    });
});
});

This is an example of my db:

{
"_id" : ObjectId("5c1e2586d695741104f724f1"),
"demographics" : {
    "farmSize" : "100",
    "crops" : "Forage Crops",
    "liveStock" : "YES",
    "precisionFarming" : "YES",
    "currentTire" : "Dealer"
},
"farmId" : "mAje06ni",
"companyName" : "xxxx",
"firstname" : "xxxxx",
"address" : "xxxxxx",
"city" : "Roma",
"state" : "Italy",
"postalcode" : "xxxxx",
"country" : "Italia",
"telephone" : "xxxxxxxxx",
"email" : "xxxxxxxxxx",
"lat" : 41.7476267,
"lon" : 12.3648812,
"__v" : 0
}

/* 4 */
{
"_id" : ObjectId("5c1e4f2dbc87ba0730969f07"),
"demographics" : {
    "farmSize" : "200",
    "crops" : "Forage Crops",
    "liveStock" : "YES",
    "precisionFarming" : "YES",
    "currentTire" : "Special Tire"
},
"farmId" : "mAje06ni",
"companyName" : "xxxxxx",
"firstname" : "xxxxxx",
"address" : "xxxxxxxxx",
"city" : "Roma",
"state" : "Italy",
"postalcode" : "00100",
"country" : "Italy",
"telephone" : "xxxxxx",
"email" : "xxxxxxxxxxxxxx",
"timestamp" : ISODate("2018-10-16T16:00:00.000Z"),
"lat" : 41.752784,
"lon" : 12.368663,
"__v" : 0
}

I need array result into identify_farms. Why my result is empty? Thanks

3
  • Can you show us sample of your db? you can empty the fields. Also instead of console.log(Farm.find({farmId:user.farmId})); do console.logs(farms) Commented Dec 22, 2018 at 15:33
  • I have update my code with db example Commented Dec 22, 2018 at 15:38
  • Are you using Mongoose? Commented Dec 22, 2018 at 15:45

2 Answers 2

1

So the issue is with where you are initializing your array, put it before your find. I edited your code, take a look at it.

Also your main issue is farms is an array therefore farms._id doesn't exist. find finds an array if you want to find only 1 then you use findOne

router.post('/login', function(req, res) {
User.findOne({ username: req.body.username}, function(err, user) {
    if (err){
        return res.status(500).send('Error on the server.');
    }
    if (!user){
        return res.status(401).send({status: 'ko', error: {msg: 'The username ' + req.body.username + ' is not associated with any account.'}});
    }
    var passwordIsValid = bcrypt.compareSync(req.body.password, user.password);
    //if (!passwordIsValid) return res.status(401).send({ auth: false, token: null });
    if (!passwordIsValid){
        return res.status(401).send({status: 'ko', error: {msg:'Authentication failed. Wrong password.',auth: false, token: null}});
    }
    // Make sure the user has been verified
    if (!user.isVerified){
        return res.status(401).send({status: 'ko', error: {type: 'not-verified', msg: 'Your account has not been verified.'}});
    }
    if (!user.statusUser){
        return res.status(401).send({status: 'ko', error: {msg: 'The username ' + req.body.username + ' is blocked by Admin'}});
    }
    // if user is found and password is valid
    // create a token
    var token = jwt.sign({ id: user._id }, config.secret, {
      expiresIn: 86400 // expires in 24 hours
    });

    // inserimento farm id //
    Farm.find({ farmId: user.farmId}, (err, farms) => {
        var identify_farm = [];

        farms.forEach(function(farm){
           console.log(farm);
           if (farm) {
            identify_farm.push(farm._id);
           }
        })

    // inserimento farm id //

    // return the information including token as JSON
    req.session.user = user;
    res.status(200).send({status: 'ok', data: {auth: true, token: token, farmId: user.farmId, roles: user.roles, id_utente: user._id, identify_farms: identify_farm}});
    });
});
});
Sign up to request clarification or add additional context in comments.

4 Comments

Hi Muhad i have tried your code by the array result is always null, instead if i use findOne i have one result
Correct; however, you can not access farms._id because its an array so one thing you can do is loop through it and add to your array, I will update my answer right now.
Yes, now is ok but using find() and not findOne(). Thanks for your help
Yup sorry I meant to change it to find I fixed it now
0

Assuming that you are using the MongoDB driver and not Mongoose, collection.find returns a cursor and not an array. For it to return documents you need to call the toArray() method on it like this

Farm.find({ farmId: user.farmId}).toArray((err, farms) => {
    console.log(Farm.find({farmId:user.farmId}));
    var identify_farm = [];
    if (err) {
        //return res.status(400).send({ status: 'ko', data: {msg: err.message }});
        var txt = err.message;
        identify_farm.push(txt);
    }
    if (!farms) {
        //return res.status(404).send({ status: 'ko', data: {msg: 'Farm not found.'}});
        identify_farm.push('Farm not found.');
    }
    if (farms) {
        identify_farm.push(farms._id);
    }

1 Comment

Hi Imre_G, i use mongoose. I have try your code and .toArray is not a function for Mongoose

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.