1

I have two models, Game and User. Game model is

const GameSchema = new Schema({
  date: String,
  time: String,
  duration: Number, // minutes
  location: [{ type: Schema.Types.ObjectId, ref: 'Court' }],
  players_needed: Number,
  max_players: Number,
  level: Number,
  players_list: [{ type: Schema.Types.ObjectId, ref: 'User' }], // players_list: [{ type: String }],
  players_status: [{ playerId: String, status: String }], // status -joined or evaluted
  postGameEvaluation: [{ playerId: String, evaluations: { } }],
  author: { type: Schema.Types.ObjectId, ref: 'User' },
});

and User model is

const UserSchema = new Schema({
  email: { type: String, unique: true, lowercase: true },
  password: { type: String },
  handle: { type: String }, //   handle: { type: String, unique: true, lowercase: true },
  games: [{ type: Schema.Types.ObjectId, ref: 'Post' }], // games and status
});

And I am trying to check if a User is already in the players_list of a Game using this

  if (req.body.players_list.filter((e) => { return e._id === req.user._id; }).length > 0) {
.....

However, even when the User is already in the game, the if statement fails to check it. For example, here are two instances of a Game and User object where the if statement fails. This is the Game object

{ location: [],
  players_list:
   [ { games: [],
       _id: '5b0cb9ff4a9c6a536d075f48',
       email: 'efafesfse',
       password: '$2a$10$bo1q0udXhL5ZnA9PMUZX4ufR0w0tcL5TmDARqAT5RpqfXheVtK3v2',
       handle: 'FSEFSEFSE',
       __v: 0,
       id: '5b0cb9ff4a9c6a536d075f48' },
     { games: [Array],
       _id: '5b0cba164a9c6a536d075f4b',
       email: 'poi',
       password: '$2a$10$sk.d5npeUMz0H9aQ6TKVzOir1j54UuXtdtQPIrxbKkwzPP07ODW/y',
       handle: 'POI',
       __v: 0,
       id: '5b0cba164a9c6a536d075f4b' },
     { games: [Array],
       _id: '5b0cba164a9c6a536d075f4b',
       email: 'poi',
       password: '$2a$10$sk.d5npeUMz0H9aQ6TKVzOir1j54UuXtdtQPIrxbKkwzPP07ODW/y',
       handle: 'POI',
       __v: 0,
       id: '5b0cba164a9c6a536d075f4b' },
     { games: [Array],
       _id: '5b0cbcd74a9c6a536d075f4e',
       email: 'bv',
       password: '$2a$10$BTvyzp9EnauZkODsg5010e/OUafNmjRbmAvJ33RslHbT.qiWTY4WC',
       handle: 'BV',
       __v: 0,
       id: '5b0cbcd74a9c6a536d075f4e' } ],
  _id: '5b0cba094a9c6a536d075f49',
  players_status:
   [ { _id: '5b0cba094a9c6a536d075f4a',
       playerId: '5b0cb9ff4a9c6a536d075f48',
       status: 'Joined' } ],
  postGameEvaluation: [],
  date: 'VVVVV',
  time: 'VVVVVVV',
  duration: 4,
  players_needed: 4,
  max_players: 4,
  level: 4,
  author:
   { games: [],
     _id: '5b0cb9ff4a9c6a536d075f48',
     email: 'efafesfse',
     password: '$2a$10$bo1q0udXhL5ZnA9PMUZX4ufR0w0tcL5TmDARqAT5RpqfXheVtK3v2',
     handle: 'FSEFSEFSE',
     __v: 0,
     id: '5b0cb9ff4a9c6a536d075f48' },
  __v: 0 }

And here is the User object that is already in the players_list of the game but the if statement fails to check for it

{ games: [ 5b0cba094a9c6a536d075f49 ],
  _id: 5b0cbcd74a9c6a536d075f4e,
  email: 'bv',
  password: '$2a$10$BTvyzp9EnauZkODsg5010e/OUafNmjRbmAvJ33RslHbT.qiWTY4WC',
  handle: 'BV',
  __v: 0 }
Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
darbulix
  • 151
  • 1
  • 1
  • 7
  • The catch here is that `_id` in both cases is actually an [`ObjectId`](http://mongodb.github.io/node-mongodb-native/3.0/api/ObjectID.html) which is a "complex JavaScript Object" and not the string values you are expecting. You can work around this using `ObjectId.equals()` i.e `filter( e => e._id.equals(req.user._id))` where both are `ObjectId` values, but there's also a much better way to get the "database" to filter these before you even return any results. As the linked answers show. [Additional `equals()` usage example here](https://stackoverflow.com/a/50499674/2313887) – Neil Lunn May 29 '18 at 03:02
  • @NeilLunn I tried your code, but I got `TypeError: e._id.equals is not a function` – darbulix May 29 '18 at 04:05
  • It's not really "the solution" and if the any of those are "strings" then you actually need to "cast" as `ObjectId` any. What I said is "it's a hack". The **solution** is to get the database to filter the list "before" you return to the client. That's what the big prominent links above your question are for. Don't return things from the database you only want to discard in client processing. – Neil Lunn May 29 '18 at 04:26
  • @NeilLunn you mean to directly filter the list through a mongodb query? If so, how would you do that? I am very new to mongodb. – darbulix May 29 '18 at 16:44
  • ***"....That's what the big prominent links above your question are for. "*** - You might consider scrolling up when you read the comment. Your question was put on hold because that exact point of "how would you do that" is answered by the content in the three links contained in the very large box directly under your question title. – Neil Lunn May 29 '18 at 21:24

0 Answers0