3

So I am currently extremely confused when it comes to mongoose populating.

My data structure is as follows: User has an array of Clients, a Client has an array of loans. I am using User.find and populating the client, no problem. But then how do I populate the loans that is inside of the client? I have tried this:

Basically, the goal is to pass in an array of Clients, each client will contain a loan. But for now, I want that loan object to be empty. The Client is being populated correctly, however, the Loan reference is being passed as undefined.

app.get("/loans", IsLoggedIn, function(req, res) {
  User.findById(req.user._id).populate({path: "clients", populate: { path: "loans", model: "loan"}}).exec(function(err, user){
    if(err){
      console.log(err);
    } else{
        var amountRepaid = calcRepaid(user.clients.loans);
        console.log(user.clients.loans);
        res.render("index", {clients: user.clients, amountRepaid: amountRepaid});
    }
  });

However it doesn't seem to work, my models are listed below and any help is appreciated!

models:

Client:

var mongoose = require("mongoose");
var clientSchema = mongoose.Schema({
  loans: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: "loan"
  }],
  emailAdderess: String,
  firstname: String,
  lastname: String,
  contactNumber: String ,
  dateCreated: {type: Date, default: Date.now},
  gender: String,
})

module.exports = mongoose.model("Client", clientSchema);

User:

const mongoose = require("mongoose");
const passportLocalMongoose = require("passport-local-mongoose");
var UserSchema = mongoose.Schema({
  username: String,
  password: String,
  firstname: String,
  lastname: String,
  clients: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: "Client"
  }]
});
UserSchema.plugin(passportLocalMongoose);

module.exports = mongoose.model("User", UserSchema);

Loan:

var mongoose = require("mongoose");

var LoanSchema = mongoose.Schema({
  firstName: String,
  lastName: String,
  email: String,
  contactNumber: Number,
  amountBorrowed: Number,
  length: String,
  address: String,
  dateDue: Date,
  gender: String,
  date: { type: Date, default: Date.now },
  amountRepaid: { type: Number, default: 0},
  loanRepaid: {type: Boolean, default: false}

})

module.exports = mongoose.model("loan", LoanSchema);
6
  • 1
    When asking questions here, please to not use external links or images of of code and include the relevant code in the question. Also it helps to make the example reproducible, and in this case that would mean including a "sub-set" of the relevant data which should produce the expected result. See How to create a Minimal, Complete, and Verifiable example. Your likely cause here is that the references to not actually match between models. This is what you should look at, and if you cannot resolve then provide enough data to return at least one result. Commented Aug 8, 2017 at 0:58
  • What is the mongoose version you are using? Commented Aug 8, 2017 at 6:47
  • @NeilLunn Sorry posted this just before I went to bed after trying to fix it for hours, my bad. The reason I didn't include a sub-set of data is because I'm not using one. I want to pass in an empty array at the beginning and the User would later add to it. I'll add that to the question. I don't understand what you mean when you say the references do not match between models? Could you possibly expand a bit? Thanks. Commented Aug 8, 2017 at 13:00
  • @ryder I am using version 4.11.5 Commented Aug 8, 2017 at 13:02
  • @Cathal did you ever figure this out? I'm having the exact same issue. Commented Jul 20, 2018 at 21:13

2 Answers 2

3

Try this:

.populate({
    path: 'clients',
    populate: {
        path: 'clients.loans'
    }
})
Sign up to request clarification or add additional context in comments.

5 Comments

This seems to make things work as clients isn't being populated, which means loans isn't populated either
Hmmn weird, I used to do it this way and it worked for me... try removing the model part in the nested populate? I don't think it's necessary.
I have genuinely tried about 8 different syntax for the populate method and none seem to work and I am not sure why. Yeah I tried removing the model and it didn't work either, have tried having the second populate as "clients.loans" and just "Loans" and that didn't work either.
Oh I see the problem. You're trying to access 'user.clients.loans' but user.clients is an array, so the correct way to do it would be 'user.clients[i].loans'
Okay sounds promising! I'm going to try this and create some sample data and see if it works, thanks! I'll come back and let you know
0

Try this:

const User=require('../models/user') <-- change path to your user schema
const Loan=require('../models/loan') <-- change path to your loan schema

User.findById(req.user._id).populate({path: 'clients', model: Loan})

Comments

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.