Storing and Returning an ObjectId in MongoDB (MEAN Stack)

1.9k Views Asked by At

I'm new to the MEAN stack and am having trouble with how to correctly link an ObjectId with MongoDB from my javascript. I am also trying to then get the name that corresponds to that ObjectId to show in my view.

The code is meant to make appointments in a schedule, where users are tied to each appointment, then the view shows information about each appointment (ie. each user's name).

Here is my Schema for the Schedule:

'use strict';

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var ScheduleSchema = new Schema({
  description: String,
  category: [String],
  location: String,
  startDate: { type: Date, default: Date.now },
  endDate: { type: Date, default: Date.now },
  participants: [{
    type: Schema.Types.ObjectId,
    ref: 'User'
  }],
  author: {
    type: Schema.Types.ObjectId,
    ref: 'User'
  },
  timestamp: { type: Date, default: Date.now },
  active: Boolean
});

module.exports = mongoose.model('Schedule', ScheduleSchema);

And the Schema for the Users:

var UserSchema = new Schema({
  name: String,
  email: { type: String, lowercase: true },
  role: {
    type: String,
    default: 'user'
  },
  hashedPassword: String,
  provider: String,
  salt: String
});

There's a lot more to that ^ file but I think the schema is the only relevant part.

And here is my controller code that passes fake testing info with 2 real user objectids (participants):

// Use our rest api to post a new meeting
$scope.addMeeting = function() {
  $http.post('/api/schedules', { description: "Testing schedule adding", participants: ["547f03befccbd4f93874b547", "5481dcbf5dad7f735a766ad9"], category: "1", location: "Small Conference Room", startDate: new Date(), endDate: new Date(), timestamp: new Date(), active: true });
};

I've gotten that to post fine, but when I get all the appointments from the schedule and put them on the view, (maybe obviously) the ObjectId is displayed rather than the name, so this:

<table style="width:100%;">
  <tr>
    <td class="left" ng-class="'head'">Time</td>
    <td ng-class="'head'">Attendees</td>
    <td ng-class="'head'">Description</td>
    <td class="right" ng-class="'head'">Location</td>
  </tr>
    <tr ng-repeat="meeting in meetings">
      <td class="left" ng-class-even="'even'">{{ meeting.startDate | date:"h:mma" }} - {{ meeting.endDate | date:"h:mma" }}</td>
      <td ng-class-even="'even'"><span ng-repeat="person in meeting.participants">{{ person }}<span ng-hide="$last">, </span></span></td>
      <td ng-class-even="'even'">{{ meeting.description }}</td>
      <td class="right" ng-class-even="'even'">{{ meeting.location }}</td>
    </tr>
</table>

Turn into this: (I had an image posted but I don't have enough reputation points, so all the picture showed was the ObjectIds of the Users underneath the 'Participants' column instead of the names)

And I'm wondering how you're supposed to properly link things to be able to show the name instead of those ObjectIds.

Sorry for the novel, hope I put enough to make it clear.

1

There are 1 best solutions below

2
On

As you are using Mongoose, use populate to load relations. In MongoDB you are storing user._id in schedule.participants, so when you list your schedules, or query for exact Schedule make sure you populate schedule.participants array.

http://mongoosejs.com/docs/populate.html

Example

Schedule
.findOne({ title: 'Once upon a timex.' })
.populate('participants')
.exec(function (err, story) {
if (err) return handleError(err);
  console.log('The creator is %s', story._creator.name);
  // prints "The creator is Aaron"
})

Also angular code should bind to name or email of user as needed. {{ person.name }}