Skip to content

0.2.18 $stateChangeSuccess not fired during (fired before?) state's controller construction #2578

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

Closed
rcollette opened this issue Feb 24, 2016 · 5 comments
Labels

Comments

@rcollette
Copy link

We had this code in the constructor (TypeScript) of a controller which was working fine while we had a resolve defined on the controller's state that was doing an XHR request.

  this._stateChangeRemoveListener = $scope.$on('$stateChangeSuccess', () => {
    if ($state.current.name === this._currentState) {
      this._initialize();
    }
  });

The code is necessary not just for initial controller construction but also when we return to the state from a child state in which case the controller is not reconstructed and we want to re-initialize the state of the controller.

When we removed the resolve from the state, we noticed the $stateChangeSuccess event was no longer being fired or it had been fired prior to creating the listener in the controller's constructor.

I added back a fakeResolve on the state of:

      resolve: {
        fakeResolve: ['$q', '$timeout', function ($q:ng.IQService, $timeout:ng.ITimeoutService) {
          let deferred = $q.defer<any>();
          $timeout(() => {
            deferred.resolve(true);
          }, 200);
          return deferred.promise;
        }]
      },

And the $stateChangeSuccess handler was being triggered again (I could go as low as 140ms but I couldn't get consistent handler calls).

What is the proper way to initialize a controller that ensures that the stateChange has succeeded before running controller initialization logic?

I would have thought the controller construction sequence would not vary in relation to the stateChangeSuccess event. Am I missing something in the documentation?

Thank you.

@rcollette
Copy link
Author

Could this be similar to #2048

@christopherthielen
Copy link
Contributor

I think this is very likely related to the code we added for #1643

I think we will be reverting that code in 0.2.19 in favor of exposing the animation promise: #2562

See also #2485

@rcollette can you try adding noanimation to your ui-view tag?
<div ui-view noanimation></div>

@rcollette
Copy link
Author

Sorry it took so long to respond.

I used noanimation but via hacking the source to just return the statics in the getRenderer method (would be nice if this could be done globally via a provider option).

That didn't help. What I've been able to observe is that the $stateChangeSuccess handler in my view controller works when line 3956 of the ui-view directive

        scope.$on('$stateChangeSuccess', function() {
          updateView(false);
        });

is called before $stateChangeSuccess is broadcast on line 3352. It seems somewhat random as to when this happen and is infrequent when using 200ms in the fakeResolve timer I mentioned previously. If I bump the timer up to 800ms, ui-view registers the handler every time prior to $stateChangeSuccess being raised.

It appears that $stateChangeSuccess is being raised before the root ui-view is compiled.

@christopherthielen
Copy link
Contributor

Oh, I see... you are trying to listen for the $stateChangeSuccess that triggered the ui-view to load? That only works if loading the ui-view happens completely synchronously. It's synchronous only in the most simple cases. In general, you should assume that the ui-view could be loaded async could be async stuff between the state change and the ui-view loading.

If you examine these lines: https://github.com/angular-ui/ui-router/blob/legacy/src/viewDirective.js#L203-L205 , you can see that ui-view is indeed loaded in response to a $stateChangeSuccess event.

@stale
Copy link

stale bot commented Jan 24, 2020

This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs.

This does not mean that the issue is invalid. Valid issues
may be reopened.

Thank you for your contributions.

@stale stale bot added the stale label Jan 24, 2020
@stale stale bot closed this as completed Feb 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants