[SOLVED] observeChanges always triggering added listener

There’s an expensive render in my app that often happens needlessly because useTracker / useCursor fires a forceUpdate() where it shouldn’t.

To track down the issue, I set up a cursor manually:

const b2 = useMemo( () => (
  Board.find({ _id: boardId }, { fields: { name: 1 } })
), [] )

b2.observeChanges({
  added: ( id, fields ) => console.log( 'added', id, fields ),
  changed: ( id, fields ) => console.log( 'changed', id, fields ),
})

I saw some weird stuff happening. When I change the name in the database, this is the DDP traffic:

image

I would expect the changed observer to be called once. However, what I’m seeing in the console is three changed calls followed by two added calls:

image

Uhh… What??

Especially the two added calls at the end are problematic, as they are always fired, even when the field has not changed (when another field was updated).

Does anybody have an idea what’s going on here (@captainn maybe)? Has anyone encountered this issue?

That looks like something in DDP - I know that even when you only subscribe to a subset of properties on a document, it’ll still react to changes to other properties.

1 Like

Wow, kind of surprised looking at the observeChanges source. Most of it is ancient (3y old), plain JS, and it’s full of // XXX comments. I was kind of expecting this core part to be more robust. But if it works, it works I guess. :upside_down_face:

The code is very opaque though, hard to see what’s going on.

Never mind, the extra calls were just because I didn’t wrap b2.observeChanges in a useEffect. :man_facepalming: