Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Results.removeAllListeners throw Error: Value is undefined, expected an Object #6217

Closed
rossicler-hostalky opened this issue Oct 25, 2023 · 4 comments
Assignees
Labels
Encryption:Off Frequency:Always More-information-needed More information is needed to progress. The issue will close automatically in 2 weeks. O-Community Repro:Always SDK-Use:Sync T-Bug Waiting-For-Reporter Waiting for more information from the reporter before we can proceed

Comments

@rossicler-hostalky
Copy link

rossicler-hostalky commented Oct 25, 2023

How frequently does the bug occur?

Always

Description

First of all, this error is only happening in React Native, I use the same code in a Electron/NodeJS environment and it works as expected.

Expected to call removeAllListeners and successfully remove listeners. Instead it gives me the error Error: Value is undefined, expected an Object.

To better understand this issue, you can check this link to see how I'm calling removeAllListeners function, because I don't keep a reference of Realm.Results, so instead I keep a reference of the removeAllListeners function.

Stacktrace & log output

Error: Value is undefined, expected an Object
Error: Value is undefined, expected an Object
    at removeAllListeners (native)
    at ?anon_0_ (http://localhost:8081/index.bundle//&platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.app.myapp:243942:18)
    at next (native)
    at anonymous (http://localhost:8081/index.bundle//&platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.app.myapp:243884:73)
    at tryCallTwo (http://localhost:8081/index.bundle//&platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.app.myapp:38616:9)
    at doResolve (http://localhost:8081/index.bundle//&platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.app.myapp:38755:25)
    at Promise (http://localhost:8081/index.bundle//&platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.app.myapp:38635:14)
    at anonymous (http://localhost:8081/index.bundle//&platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.app.myapp:243866:36)
    at testUnsub2 (http://localhost:8081/index.bundle//&platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.app.myapp:243933:21)
    at anonymous (http://localhost:8081/index.bundle//&platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.app.myapp:634210:33)
    at commitHookEffectListMount (http://localhost:8081/index.bundle//&platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.app.myapp:96239:38)
    at commitPassiveMountOnFiber (http://localhost:8081/index.bundle//&platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.app.myapp:97440:44)
    at commitPassiveMountEffects_complete (http://localhost:8081/index.bundle//&platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.app.myapp:97412:40)
    at commitPassiveMountEffects_begin (http://localhost:8081/index.bundle//&platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.app.myapp:97402:47)
    at commitPassiveMountEffects (http://localhost:8081/index.bundle//&platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.app.myapp:97392:40)
    at flushPassiveEffectsImpl (http://localhost:8081/index.bundle//&platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.app.myapp:99068:34)
    at flushPassiveEffects (http://localhost:8081/index.bundle//&platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.app.myapp:99023:43)
    at anonymous (http://localhost:8081/index.bundle//&platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.app.myapp:98856:34)

Can you reproduce the bug?

Always

Reproduction Steps

Example that throws the error:

let unsubListener: (() => void) | undefined;
export const getItems = async () => {
  ...
  const items = realm.objects(ItemSchema);
  await realm.subscriptions.update((mutableSubs) => {
    mutableSubs.add(items, { name: "items" });
  })
  
  if (unsubListener) unsubListener();
  items.addListener(itemListener);
  unsubListener = items.removeAllListeners;
  ...
}

The first execution will always work as expected, but the second time this function is called, unsubListener will have a reference to items.removeAllListeners, and by calling unsubListener(), it throws the error mentioned in this issue.

Example that works as expected:

let results: Realm.Results<ItemSchema & Realm.Object<unknown, never>> | undefined;
export const getItems = async () => {
  ...
  const items = realm.objects(ItemSchema);
  await realm.subscriptions.update((mutableSubs) => {
    mutableSubs.add(items, { name: "items" });
  })
  
  if (results) results.removeAllListeners();
  items.addListener(itemListener);
  results = items;
  ...
}

I noticed that this issue is related to keeping the reference of removeAllListeners in a variable, because the code above works without any issue, but I didn't want to keep a reference of all results just to remove listeners later on. What I can't figure it out is why does it work fine in a NodeJS environment, but not on React Native.

Version

11.7.0

What services are you using?

Atlas Device Sync

Are you using encryption?

No

Platform OS and version(s)

macOS Monterey 12.6

Build environment

Which debugger for React Native: ..

Cocoapods version

No response

@kneth
Copy link
Contributor

kneth commented Oct 26, 2023

@rossicler-hostalky Thank you for the detailed analysis

why does it work fine in a NodeJS environment, but not on React Native

My guess is that the garbage collector on React Native is more aggressive, and items is quickly claimed when it goes out of scope.

You should probably create a closure to caption the Realm.Results object to be able to remove all the listeners when needed.

@sync-by-unito sync-by-unito bot added the Waiting-For-Reporter Waiting for more information from the reporter before we can proceed label Oct 26, 2023
@rossicler-hostalky
Copy link
Author

@kneth Thanks for the reply.

You should probably create a closure to caption the Realm.Results object to be able to remove all the listeners when needed.

Can you give an example of how to achieve that?
Also, this would mean that I would need to keep a reference to all objects inside Realm.Results, right?

For now I'm using the code from the example that works as expected, keeping a reference to Realm.Results, but I'm not entirely happy with it, since all I want is to remove listeners later on.

@github-actions github-actions bot added Needs-Attention Reporter has responded. Review comment. and removed Waiting-For-Reporter Waiting for more information from the reporter before we can proceed labels Oct 26, 2023
@nirinchev
Copy link
Member

I believe @kneth's suggestion is to create a lambda and return that rather than a reference to items.removeAllListeners. In your code, that would look something like:

-unsubListener = items.removeAllListeners;
+unsubListener = () => { 
+	items.removeAllListeners();
+};

@sync-by-unito sync-by-unito bot added the Waiting-For-Reporter Waiting for more information from the reporter before we can proceed label Mar 20, 2024
@sync-by-unito sync-by-unito bot added More-information-needed More information is needed to progress. The issue will close automatically in 2 weeks. and removed Needs-Attention Reporter has responded. Review comment. labels Mar 20, 2024
Copy link
Contributor

github-actions bot commented Apr 4, 2024

This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further.

@github-actions github-actions bot closed this as completed Apr 4, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 4, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Encryption:Off Frequency:Always More-information-needed More information is needed to progress. The issue will close automatically in 2 weeks. O-Community Repro:Always SDK-Use:Sync T-Bug Waiting-For-Reporter Waiting for more information from the reporter before we can proceed
Projects
None yet
Development

No branches or pull requests

3 participants