Realm.Collection => addListener()

Hi There,

I have always struggled with the API for listening to changes on a collection.
@Ian_Ward - maybe you could shed some light on this?

The current API from the 10.0.0-beta.12 docs is:

interface CollectionChangeSet {
        insertions: number[];
        deletions: number[];
        newModifications: number[];
        oldModifications: number[];
    }

type CollectionChangeCallback<T> = (collection: Collection<T>, changes: CollectionChangeSet) => void;
  • collection : the collection instance that changed,
  • changes : a dictionary with keys insertions , newModifications , oldModifications and deletions , each containing a list of indices in the collection that were inserted, updated or deleted respectively. deletions and oldModifications are indices into the collection before the change happened, while insertions and newModifications are indices into the new version of the collection.

Whilst it’s pretty trivial to manage insertions and newModifications, I can’t quite figure out the best way to manage deletions and oldModifications.

Lets focus on deletions for a moment (mostly because I don’t know what oldModifications would even be useful for - For that matter, even newModifications doesn’t really help that much other than letting me know that something changed… see my second point below)

I’m not sure I fully understand how to leverage these deletion indices on a collection that changes over time.

Lets say we have a collection => [obj1, obj2, obj3, obj4]

Some time later, a change comes through and our listener is called with:
( [obj1, obj3, obj4], { deletions: [1] } ) => ...

So what am I to do with this index?

Let’s say in my case that to do something useful with this information I need the ID of the deleted object (obj2) - I do not use the results collection in an array, and even if I were, I would be forced to maintain the original order for the index to be meaningful.

Do I have to keep an array of IDs inside the listener and reference/mutate that in sync with the changes to the original collection?

I don’t imagine it would work to close over the original results collection and reference the object in that - if it is deleted, it won’t be there any more…
Besides, what happens the next time a change occurs in this collection, the original results collection would be stale.

Surely the API for these changes - especially deletions, should at least be an array of objects like:

[
    {
        index: <index of inserted/modified/deleted item>,
        id: <ID of inserted/modified/deleted Item>
    }
]

Secondly,
Lets say I wanted to listen for changes to individual objects in a collection. (The current API just says “something changed in the item at index x”)
Would the best approach be to map over the results and to add individual listeners to the constituent objects? This seems like what you’d need to do - but maybe the collection listener API needs an overhaul to encapsulate useable info like the the much more easily consumable ObjectChangeCallback API.
i.e.

interface ObjectChangeSet {
    deleted: boolean;
    changedProperties: string[]
}

That way we can use similar approaches for listener callbacks on both collections and individual objects.

Either way - some guidance on this would be great.

Thanks in advance!

B

The idea here is to use them to update your UI. If you have a UITableView, for example, you can tell it that the cell with index 1 was removed and it will animate everything correctly. Same with newModifications - you can tell your tableview that the cell with index X was modified, so it needs to be redrawn. Then it will invoke the GetCellAtIndex (or whatever the correct method name is) and fetch the new data from the collection.

These indices are for creating a slick UI/UX - you don’t need to use them. For instance in React, you have to tell it to just redraw everything so the indices are less useful. You could just clobber the TableView and redraw everything - most of the time the user won’t notice - it depends on your use case.

I take your point though and we are looking at ways to improve this in future - for instance, by leveraging frozen realms automatically in change notifications which we believe would improve developer experience. Stay tuned.

Hi @Ian_Ward

Thanks for the feedback.

Indeed - I’m using react - so I don’t especially want to clobber the UI.
This is why I’m interested in more detail in the notifications.

So - in short, I’m not missing anything. It’s just not been designed with my use case in mind.
I’m very interested in a better API here - if you need further input let me know.

Until then I’ll just have to roll my own solution.

B

Cheers

B