realm-js icon indicating copy to clipboard operation
realm-js copied to clipboard

Able to add but unable to remove change listener on collection of embedded objects

Open atomfried opened this issue 2 years ago • 4 comments

How frequently does the bug occur?

All the time

Description

I have a collection of embedded objects like so (schema):

const FooSchema = {  { embedded: true, name: 'Foo, properties: { /*...*/}  };
const BarSchema = { name: 'Bar', properties: { foos: { type: 'list', objectType: 'Foo' } } };

If I do something like this...

const bar = realm.objects('Bar')[0];
const listener = foos => console.log('listening to the foos');
bar.foos.addListener(listener); // This will succesfully register the listener
bar.foos.removeListener(listener); // This however will absolutely totally not remove the listener!
bar.foos.removeAllListeners(); // This will not remove it either!!!

Am I doing it wrong or Is this a bug or am I just not meant to listen in on the (embedded) foos? If the latter why can I?

I hope I'm in the right place with this...?

Thx + peace

Stacktrace & log output

No response

Can you reproduce the bug?

Yes, always

Reproduction Steps

I was to lazy to write a proper standalone example but I might be persuadable to do so.

Version

10.11.0

What SDK flavour are you using?

Local Database only

Are you using encryption?

No, not using encryption

Platform OS and version(s)

react native @ android

Build environment

Which debugger for React Native: ..

Cocoapods version

No response

atomfried avatar Apr 05 '22 13:04 atomfried

Correction: The objects do not have to be embedded for me to be unable to remove listeners from a collection. The only thing that works for me is registering/removing listeners directly on the result of realm.objects / realm.objectForPrimaryKey. Listeners on anything inside the result object/collection cannot be removed... Is this documented anywhere?

atomfried avatar Apr 05 '22 18:04 atomfried

Good news everyone

Realm isn't broken, just tricky to use... and a little bit broken one might argue... :) For posterity:

// What I did:
const bar = realm.objects('Bar')[0];
useEffect(() => {
  const listener = console.log;
  bar.foos.addListener(listener);
  return () => bar.foos.removeListener(listener);
},[]);

// What i should have done instead:
const bar = realm.objects('Bar')[0];
useEffect(() => {
  const foos = bar.foos;
  const listener = console.log;
  foos.addListener(listener);
  return () => foos.removeListener(listener);
},[]);

Basically the issus is this:

const bar = realm.objects('Bar')[0];
const foos = bar.foos;
doSomeChangeToTheFoos(bar.foos);
console.log(foos == bar.foos); // true!!
console.log(foos.removeListener == bar.foos.removeListener); // false!!

It's up to devs whether this should be considered a bug. If it isn't feel free to close.

atomfried avatar Apr 05 '22 19:04 atomfried

@atomfried Thank you for your investigation.

Realm isn't broken, just tricky to use

For us, it is important that it is not tricky to use. So I will leave the issue open for us to remember to visit the listener API in the near future.

kneth avatar Apr 08 '22 13:04 kneth

@atomfried Thank you for this! I would agree it is confusing.

mountain-hiker avatar Jul 17 '22 16:07 mountain-hiker

Good news everyone

Realm isn't broken, just tricky to use... and a little bit broken one might argue... :) For posterity:

// What I did:
const bar = realm.objects('Bar')[0];
useEffect(() => {
  const listener = console.log;
  bar.foos.addListener(listener);
  return () => bar.foos.removeListener(listener);
},[]);

// What i should have done instead:
const bar = realm.objects('Bar')[0];
useEffect(() => {
  const foos = bar.foos;
  const listener = console.log;
  foos.addListener(listener);
  return () => foos.removeListener(listener);
},[]);

Basically the issus is this:

const bar = realm.objects('Bar')[0];
const foos = bar.foos;
doSomeChangeToTheFoos(bar.foos);
console.log(foos == bar.foos); // true!!
console.log(foos.removeListener == bar.foos.removeListener); // false!!

It's up to devs whether this should be considered a bug. If it isn't feel free to close.

This is works! But I'm sorry to say that [email protected] still has this problem 😂

devethan avatar Dec 28 '23 18:12 devethan

@devethan have you tried with v12? This is a complete rewrite of the SDK and on the top of my head, I can't see why v12 would show the same behaviour.

kraenhansen avatar Dec 28 '23 19:12 kraenhansen

@kraenhansen No, I haven't. Actually I'd love to update to v12, but I don't have the time for now 😂

I think the problem is related to the endpoint of the listener.

I added a listener to bar.foos, but when I delete it, it doesn't find the listener in bar.foos, so I can't delete it. By @atomfried workaround, I assigned the bar.foos object to a variable, and this problem goes away.

devethan avatar Dec 29 '23 14:12 devethan

I don't have the time for now

Although v12 is a complete rewrite of the SDK, we took a lot of care to minimize breaking changes. If you have any issues simply upgrading by npm install realm@latest we'd love to know here: https://github.com/realm/realm-js/discussions/5416

As to the original issue, I'd go ahead and close this for now - if you see this reappear in v12, please feel free to open a new issue 👍

kraenhansen avatar Dec 29 '23 15:12 kraenhansen