0

I'm writing a little planning poker tool in Meteor; first time working with meteor and json document stores. I have a Collection for user stories, along with the users assigned to that story and ratings from those users.

Initially I'll do some inserts like this:

Stories.insert({'story': stories[i], 'assignees': users, 'ratings': []});

... and one entry might look like this:

{
  'story': 'some story',
  'assignees': ['Bob', 'Joe'],
  'ratings': []
}

Then, once a user has entered their rating for that story, it should be updated to look something like this:

{
  'story': 'some story',
  'assignees': ['Bob', 'Joe'],
  'ratings': [{'Bob': 2}, {'Joe': 5}] // maybe a better way to do this?
}

I'm having trouble writing the line to make that happen. What I have now is:

var users = ['Bob', 'Joe'];
for (var i = 0; i < users.length; i++) {
  var user = users[i];
  var rating = {user: 1};
  Stories.update({}, {$push: {'ratings': rating}});
}

Unfortunately, the result is something like:

{
  'story': 'some story',
  'assignees': ['Bob', 'Joe'],
  'ratings': [{user: 1}]
}

That is, only one object in the ratings array, and not even of the correct key (plain user instead of something like Bob). This may have something to do with JS hoisting and object instantiation being tricky. Any insight is appreciated.

2
  • 1
    The code you show does exactly what it should as the object you specified as rating has been "pushed" onto the array. Are you actually asking how to "push" { "user1": 1 } and { "user2": 2 } onto the array with one statement? Commented May 27, 2014 at 2:39
  • @NeilLunn I should have added more context. You can now see the loop logic and a sample array of users above those lines. I also added another sentence at the end to explain that I'm getting only one object in the ratings array, with no relevant key. Commented May 27, 2014 at 3:15

1 Answer 1

4

Your problem is you are trying to use a variable as a "key" for the object, which does not work that way. User the bracket [] notation in order to dynamically assign the "key" instead as follows:

var users = ['Bob', 'Joe'];
for (var i = 0; i < users.length; i++) {
  var user = users[i];
  var rating = {};
  rating[user] = 1;
  Stories.update({}, {$push: {'ratings': rating}});
}

Actually you can even do this better with a single update:

var users = ['Bob', 'Joe'];
var ratings = [];
for (var i = 0; i < users.length; i++) {
  var user = users[i];
  var rating = {};
  rating[user] = 1;
  ratings.push( rating);
}

Stories.update({}, {$push: {'ratings': { $each: ratings } }});

So the $each modifier allows you to push an "array" of new documents onto the existing array and this means less updates over the network.

Not sure where you are doing this operation from so that second choice may not be available from a browser client with minimongo. But it can be invoked that way from the server.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.