Open mikeknerr opened 2 years ago
Hi, watching your code it seems that
foods: [
{
adjQuantity: Number,
name: String,
matchingMealPlanFoods: [{
type: Schema.Types.ObjectId,
subRef: 'MealPlanUser.foods',
}],
matchingMealPlanRecipeFoods: [{
type: Schema.Types.ObjectId,
subRef: 'MealPlanUser.recipes.foods', // <------ Here
}],
completed: Boolean,
cleared: Boolean,
},
],
the path referred by the subRef doesn't seem to exist. Which is the real intent here?
The model MealPlanUser provides a property 'recipes' but this one has no property 'foods'. Am i right?
The recipe path is a reference to another schema, RecipeUser, which has a property of foods:
const RecipeUserSchema = new Schema({
name: {
type: String,
required: true,
},
foods: [{
quantity: {
type: Number,
default: 1,
},
measureUnit: String,
name: String,
food: {
type: Schema.Types.ObjectId,
ref: 'Food',
},
}],
},
{
toJSON: { virtuals: true },
toObject: { virtuals: true },
}); // options
However, at the moment I am testing the matchingMealPlanFoods
, which has shallower nesting, and that one still isn't populating as expected.
From what I can tell, something related to the array situation is going on here:
eachPathRecursive(schema, (path, schemaType) => {
console.log('path', path);
console.log('options', schemaType.options);
if (schemaType.options.subRef) {
populableReferencesPaths[path] = schemaType
};
});
Because for the relevant paths, this is what comes up for options:
path foods.matchingMealPlanFoods
options { type: [ { type: [Function], subRef: 'MealPlanUser.foods' } ] }
path foods.matchingMealPlanRecipeFoods
options {
type: [ { type: [Function], subRef: 'MealPlanUser.recipes.foods' } ]
| }
Therefore, none of the paths will actually be truthy for schemaType.options.subRef
since the subRef is buried in a type array.
EDIT: However, it seems that this populableReferencesPaths
object may not actually be used anywhere...
Digging further, the issue may actually be in the execute
function:
for (let option of options) {
// The schema type of sub populate's path
const localFieldSchemaType = model.schema.path(option.path)
// Do we know who is the ref to the root document of the sub reference ?
const localFieldBoundToSchemaType = localFieldSchemaType.options.boundTo
? model.schema.path(localFieldSchemaType.options.boundTo)
: null;
console.log(localFieldSchemaType.options)
It appears that the option.path
here is foods.matchingMealPlanFoods
, which makes sense, however, localFieldSchemaType resolves to undefined
. So it seems model.schema.path
may only work with top-level properties.
Out of curiosity, is this something that will be resolved/investigated in a future version?
There are many scenarios where someone would want to populate a subdocument from another model from within an array of subdocs on another model. My current use case example is this:
Meal Plan Schema (simplified)
Shopping List Schema
This throws the error
Cannot read property options of undefined
which from digging in a bit further seems to be based on this package not anticipating any deeper nesting than top-level (as shown in the examples).This seems like an important optimization, as the use case above is equally valid as a top-level reference to a subdoc on another model.