Odd different when using .populate() on a separate method between with findById() and with find()

Viewed 25

So I read my senior's code and I see he did something like this:

const getTechnicianByIdQuery = await TechnicianModel.findById({id: someId});
const wantedTechnician = await this.populateSingleTechnician(getTechnicianByIdQuery);

const populateSingleTechnician(technician: any): Promise<Technician>{
    const populatedTechnician = await technician
        .populate({path: 'salon',})
        .populate({path: 'user',})
        .execPopulate();
    return populatedTechnician;
};

This code works fine, and I think his way of doing this is cool that allow us to reuse code so I try to do the same with a different search using find() instead of findById():

const getTechnicianBySalonQuery = await TechnicianModel.find({salon: someSalonId})
const wantedTechnicianGroup = await this.populateTechnicianGroup(getTechnicianBySalonQuery);

const populateSingleTechnician(technicianGroup: any): Promise<Technician[]>{
    const populatedTechnicians = await technicianGroup
        .populate({path: 'salon',})
        .populate({path: 'user',})
        .execPopulate();
    return populatedTechnicians;
};

My code gives error:

{ errors: [ GraphQLError { message: 'technicianGroup.populate is not a function', locations: [Array], path: [Array] } ], data: null }

How come my code gives this error while his code works fine and returns the populated data? If we say separating the populating process, which is usually put in as a chaining operator, caused this error, I still wonder what difference that make the first code block works but not mine.

On the other note, I have done the tradition way of chaining populated() to the query and it worked fine.

1 Answers

When chaining, you should not use of await keyword. When you use await you execute the query.

Look at the documentation example.

const getTechnicianByIdQuery = TechnicianModel.findById({
  id: someId,
});

const wantedTechnician = await this.populateSingleTechnician(getTechnicianByIdQuery);

const populateSingleTechnician(technician: any): Promise<Technician> {
  const populatedTechnician = await technician
    .populate({
      path: 'salon',
    })
    .populate({
      path: 'user',
    })
    .execPopulate();
  return populatedTechnician;
};

The first one is working because await findById returns you a mongoose.Document that have the .populate method available. When in the second case, the mongoose.Document[] doesn't have the populate method (because it's an array).


I see that you use of typescript, I highly recommend you to type your variables. You would have seen an error at technician.populate if technician: any was replaced by the correct type.

Related