0

I have an array of ids which is launchIds. I'm trying to push it on a model field trips with $addToSet: { trips: { $each: launchIds }. This gives me an error: Cast to [ObjectId] failed for value \"[\"1\",\"2\",\"3\"]\...

if I try to map through launchIds and convert to Mongoose.Shema.Types.ObjectId I get in the database trips: [null,null,null]

lauchIds = ['1','2','3']

  async bookTrips({ launchIds }) {
    let userId = "5bf7f7b3817119363da48403";

    const mongoIds = launchIds.map(l => Mongoose.Schema.Types.ObjectId(l));

    return this.store.User.findByIdAndUpdate(
      { _id: userId },
      {
        $addToSet: { trips: { $each: mongoIds } }
      },
      { new: true }
    );
  }

Here's my model Schema:

  const UserSchema = new Mongoose.Schema(
    {
      email: {
        type: String,
        required: true
      },
      token: String,
      trips: [
        {
          type: Mongoose.Schema.Types.ObjectId,
          ref: "trip"
        }
      ]
    },
    { timestamps: true }
  );

I'm passing ids via grapql playground. Here's my mutation:

bookTrips: async (_, { launchIds }, { dataSources }) => {
  console.log(launchIds);
  // logs ['1','2','3']
  console.log(typeof launchIds);
  //Object 

  const results = await dataSources.userAPI.bookTrips({ launchIds });
  console.log(results);

  return { message: "hello" };
}
karolis2017
  • 2,195
  • 8
  • 24
  • 49

2 Answers2

0

To convert a string or a number into mongo object use Mongoose.Types.ObjectId,

const mongoIds = launchIds.map(l => Mongoose.Types.ObjectId(l));
Raja Sekar
  • 2,062
  • 16
  • 23
  • I get an error : `"Argument passed in must be a single String of 12 bytes or a string of 24 hex characters"` – karolis2017 Nov 24 '18 at 02:23
  • Mongoose.Types.ObjectId(1) => 000000012a5f832b959ac1a4. I'm getting no error. – Raja Sekar Nov 24 '18 at 02:26
  • change Mongoose.Schema.Types.ObjectId => Mongoose.Types.ObjectId – Raja Sekar Nov 24 '18 at 02:27
  • Throws me an error in the console: `node_modules/mongoose/lib/schema.js:681 throw new TypeError('Undefined type `' + name + '` at array `' + path + ^ TypeError: Undefined type `ObjectID` at array `trips`` – karolis2017 Nov 24 '18 at 02:31
  • can u check this https://repl.it/@rajasekarm/Stackoverflow-mongoose-issue-fix, click run to see the output – Raja Sekar Nov 24 '18 at 02:35
  • I think I found an issue. `const ids = ['1', '2', '3']; const idsToNums=ids.map(Number);` I'm getting an array of strings and not numbers – karolis2017 Nov 24 '18 at 02:44
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/184169/discussion-between-raja-sekar-and-karolis2017). – Raja Sekar Nov 24 '18 at 04:56
0

I was getting back an array of strings where this should be numbers

The solution:

My model (same as above):

  const UserSchema = new Mongoose.Schema(
    {
      email: {
        type: String,
        required: true
      },
      token: String,
      trips: [
        {
          type: Mongoose.Schema.Types.ObjectId,
          ref: "trip"
        }
      ]
    },
    { timestamps: true }
  );

crud API:

  async bookTrips({ launchIds }) {
    let userId = "5bf7f7b3817119363da48403";

    const idsToNums = launchIds.map(Number);
    const mongoIds = idsToNums.map(l => Mongoose.Types.ObjectId(l));

    return this.store.User.findByIdAndUpdate(
      { _id: userId },
      {
        $push: { trips: { $each: mongoIds } }
      },
      { new: true }
    );
  }

Notice the Mongoose.Schema.Types.ObjectId on model and Mongoose.Types.ObjectId on api. If I remove Schema from model or add Schema to api I'm getting an error. Not sure why, but the above example works. I hope someone will find this helpful or suggests a better solution.

karolis2017
  • 2,195
  • 8
  • 24
  • 49
  • Someone ( actually the original author ) already explained why https://github.com/Automattic/mongoose/issues/1671: – Neil Lunn Nov 24 '18 at 08:31