1

I just upgraded from Mongoose 5.5.5 to 6.0.12 and part of my code stopped working. In my sports league manager, I have a model called League which has a list of categories (groups). Each group has a list of teams. So League.groups[].teams[] I need to be able to move a single team to a different group's teams[]. So here is my code:

  const League = require('./schemas/volley/League');
  const league = new League();

  const group1 = league.groups.create({name:"Group 1"}); // create group1
  const group2 = league.groups.create({name:"Group 2"}); // create group2
  league.groups.push(group1); // add both groups to the league's list of groups.
  league.groups.push(group2);

  const team = group1.teams.create({name:"The Team To Transfer"}); // create a team
  group1.teams.push(team);  // add it to group1's teams
  team.remove();            // later, remove it from group1's teams[]
  try {
    group2.teams.push(team); // try to add it to group2's teams[]
  }
  catch (err){
    console.log(err);
  }

So in short, I created "team", added it to group1's team list (group1.teams.push). Then I need to move this team so I remove it and push it to group2's teams.

This used to work fine in Mongoose 5. Now in mongoose 6, I get the following error:

TypeError: Cannot read property '$path' of undefined
    at EmbeddedDocument.ArraySubdocument.$__pathRelativeToParent (C:\MTC\mtc_server\node_modules\mongoose\lib\types\ArraySubdocument
.js:145:29)
    at EmbeddedDocument.Subdocument.invalidate (C:\MTC\mtc_server\node_modules\mongoose\lib\types\subdocument.js:202:25)
    at $__applyDefaults (C:\MTC\mtc_server\node_modules\mongoose\lib\document.js:528:17)
    at EmbeddedDocument.Document (C:\MTC\mtc_server\node_modules\mongoose\lib\document.js:148:7)
    at EmbeddedDocument.Subdocument (C:\MTC\mtc_server\node_modules\mongoose\lib\types\subdocument.js:28:12)
    at EmbeddedDocument.ArraySubdocument [as constructor] (C:\MTC\mtc_server\node_modules\mongoose\lib\types\ArraySubdocument.js:36:
15)
    at new EmbeddedDocument (C:\MTC\mtc_server\node_modules\mongoose\lib\schema\documentarray.js:115:17)
    at DocumentArrayPath.cast (C:\MTC\mtc_server\node_modules\mongoose\lib\schema\documentarray.js:446:26)
    at DocumentArrayPath.SchemaType.applySetters (C:\MTC\mtc_server\node_modules\mongoose\lib\schematype.js:1135:12)
    at Proxy.push (C:\MTC\mtc_server\node_modules\mongoose\lib\types\array\methods\index.js:655:38)
    at Proxy.push (C:\MTC\mtc_server\node_modules\mongoose\lib\types\DocumentArray\methods\index.js:183:35)
    at testPathError (C:\MTC\mtc_server\app.js:286:18)
    at Timeout._onTimeout (C:\MTC\mtc_server\app.js:241:9)

I have found a fix for this by recreating the team from group2 as follow

const newTeam = group2.teams.create(team); // recreate the team with new parent
group2.teams.push(newTeam);                // add team to new parent

Problem is that I have a LOT of instances in my code where I move subdocuments between arrays of the same type and there is no guarantee that I won't break anything by recreating subdocuments everywhere. Is there an easy fix where I don't have to recreate the subdocument? I seem to understand that Mongoose 6 now has a "parent" property to subdocuments doesn't react well if you try to push a child to the wrong parent. (How would you react if your neighbour forced you to adopt their kids?) Perhaps there is a way to set the parent? Or a way to reset the parent link after .remove()?

0 Answers0