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

1.0 ng1: Hooks can still be called after de-register invocation #2928

Closed
jgrund opened this issue Aug 18, 2016 · 5 comments
Closed

1.0 ng1: Hooks can still be called after de-register invocation #2928

jgrund opened this issue Aug 18, 2016 · 5 comments

Comments

@jgrund
Copy link

jgrund commented Aug 18, 2016

We are seeing a case where our hook callback is invoked after de-registering it.

It seems that the callback should never be invoked after a de-register is called.

@johnsonw
Copy link

👍 , seeing the same thing.

@christopherthielen
Copy link
Contributor

Are you deregistering the hook while a transition is in process? The hook pipeline is computed when the transition starts.

What is your use case(s)?

@jgrund
Copy link
Author

jgrund commented Aug 19, 2016

So the basic scenario can be boiled down to:

   // factory
   function serviceWithTransitions ($transitions) {
     return () => 
       $transitions.onSuccess({}, console.log);
   };

  const component = {
    controller: function (serviceWithTransition) {
      this.$onDestroy = serviceWithTransition();
    },
    template: '<foo></foo>'
  }

Where component is registered as a component on a state.

What ends up happening is:

  1. $onDestroy is invoked on a route transition.
  2. The onSuccess handler is de-registered.
  3. The onSuccess handler fires for the component being navigated away from, even though it was de-registered previously.

What I considered surprising about this is that invoking the de-registration function is not upheld 100 percent of the time.

It seems like this can lead to subtle bugs as I suspect others with have the same assumption.

@christopherthielen
Copy link
Contributor

christopherthielen commented Aug 19, 2016

I see... that's helpful, thanks for the use case details.

I agree that's surprising behavior as you described.


Here's the details of why it's happening:

  1. Transition to first state
  2. Component is created, hook is registered in global registry
  3. Transition away from first state
  • onBefore hooks are fetched and sorted by priority, then run in order
  • all matching (async) hooks are fetched from global registry
  • those hooks are and sorted by hook type/hook priority, then queued for run in order
  • Transition is successful.
  1. onSuccess hooks are fetched and sorted by priority
  • your onSuccess hook is placed in the onSuccess pipeline at this time
  • Views are updated
    • The component is destroyed, hook deregister function is invoked. Hook is removed from global registry.
    • The pipeline is already computed, so is unaffected

I'm going to have to give some thought to this.

@christopherthielen
Copy link
Contributor

Fixed by #2939

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants