corvid
corvid

Reputation: 11187

Observe changes to a nested array doesn't return element added/changed

I am using an observeChanges on this cursor as follows. The cursor contains a nested array called "messages".

Connections.find({
  status: 'connected'
}).observeChanges({
  added: function (id) {
    console.log(`Connected ${id}`);
  },
  changed: function (id, fields) {
    // I expect fields to be the last array item pushed
    console.log(fields['messages']);
  }
});

However, this yields all the messages, rather than the ones changed or added. How can you just get the last ones pushed? Getting the last one won't work as intended because you can push multiple at a time.

Here is a fully working example on meteorpad if you want to see what I mean in action (look at console.logs)

Upvotes: 1

Views: 163

Answers (2)

corvid
corvid

Reputation: 11187

I've found a way to do it, it's just not using observeChanges, uses observe instead.

Connections.find({
  status: 'connected'
}).observe({
  changed: function (newDoc, oldDoc) {
    let newMessages = _.clone(newDoc.messages);
    let old = _.clone(oldDoc.messages);
    while (JSON.stringify(old) !== JSON.stringify(newMessages.slice(0, old.length))) {
      old.shift();
    }
    let last = newMessages.slice(old.length);
  }
});

Upvotes: 0

acemtp
acemtp

Reputation: 3019

You have to disable the observeChanges during the first step to only catch new things:

var init = true;
Connections.find({
  status: 'connected'
}).observeChanges({
  added: function (id) {
    if(init) return;
    console.log(`Connected ${id}`);
  },
  changed: function (id, fields) {
    if(init) return;
    // I expect fields to be the last array item pushed
    console.log(fields['messages']);
  }
});
init = false;

here is the meteorpad version:

http://meteorpad.com/pad/2NcJwxHYQNTqktMa5/Copy%20of%20Leaderboard

Upvotes: 1

Related Questions