Skip to content

Resolves aren't aborted if state is changed while resolving #2126

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
eddiemonge opened this issue Jul 24, 2015 · 10 comments
Closed

Resolves aren't aborted if state is changed while resolving #2126

eddiemonge opened this issue Jul 24, 2015 · 10 comments

Comments

@eddiemonge
Copy link
Contributor

http://plnkr.co/edit/NdkPaZQ1Yvczf8mYcMZI?p=preview

If a state (B) is transitioned to and then another state (C) is transitioned to while B's resolves are still pending, those resolves are still completed.

This present two problems:

  1. Code in them completes when perhaps they shouldn't or at least have an option to abort or complete them.
  2. State B never gets a stateChangeStart or stateChangeCancel to know that the stateChange was started but never "completed". There should be a stateChangeFinally or stateChangeAborted event, or stateChangeCancel should trigger for this scenario. see No way to respond to view state change cancellations #2123 for a use case
@nateabele
Copy link
Contributor

I don't think that's something we can make work automatically. You'd have to wire it into your $http calls. See http://odetocode.com/blogs/scott/archive/2014/04/24/canceling-http-requests-in-angularjs.aspx

@eddiemonge
Copy link
Contributor Author

Yeah 1 should be handled in the implementation. 2 however should have one of the two fire but I guess it doesn't matter with 1.0

@jullian-chavez
Copy link

Is this planned to be resolved?

@nateabele
Copy link
Contributor

Is this planned to be resolved?

@jullian-chavez I see what you did there. 😉

It's not really on the immediate horizon, as it's going to some figuring out, and we already have a bunch of work on our plates, but we're taking suggestions and ideas in the meantime.

@jullian-chavez
Copy link

Haha, didnt even notice that. Any suggestions on how to minimize this issue in the mean time? Otherwise, I think our dev team is going to take a whack at making a fix for this. We'll share if/how we are able to come to a solution for this.

@nateabele
Copy link
Contributor

Any suggestions on how to minimize this issue in the mean time?

Well, you can wrap your $http calls with something like this, and then maybe set up a watcher to match up $stateChange* events. It's not great right now, and it probably still won't be even post-1.0, but it should at least be easier.

Part of the problem is that there's no generalized way to cancel a promise, and most people wrap up their remote calls (resolves) in services.

Otherwise, I think our dev team is going to take a whack at making a fix for this. We'll share if/how we are able to come to a solution for this.

That'd be great. Looking forward to seeing what you come up with.

@Kiougar
Copy link

Kiougar commented Oct 10, 2015

I just came across the same problem. I think I can provide two solutions for the 2nd problem, each with different drawbacks.

First Solution

We should broadcast a $stateChangeCancel event every time we return TransitionSuperseded. This means we replace every line (e.g https://github.com/angular-ui/ui-router/blob/master/src/state.js#L1109):

if ($state.transition !== transition) return TransitionSuperseded;

with:

if ($state.transition !== transition) {
    $rootScope.$broadcast('$stateChangeCancel', to.self, toParams, from.self, fromParams);
    return TransitionSuperseded;
}

The only problem is that the event is triggered AFTER the resolves and not at the moment the transition is cancelled (e.g. when we set $state.transition = null)


Second Solution

We should broadcast a $stateChangeCancel event the moment the transition is cancelled. We need to check at the start of the transitionTo function if $state.transition exists. If it exists a transition is still pending and another transition gets in queue, thus, we need to cancel the pending transition and continue with the other one.

This approach needs more changes (since we need to create "global" variables to hold the to/from variables of the cancelled transition to properly broadcast the event) and is not tested (only theory-crafting).


Currently, I'm going with the first approach since it's a quick non-breaking workaround, but I personally prefer the second approach since it will be a solid base to allow us to solve the 1st problem as well (we can wrap every resolve with a promise that has an abort function and abort them when we cancel the transition).

@Kiougar
Copy link

Kiougar commented Oct 11, 2015

@nateabele @eddiemonge Any thoughts?

@nateabele
Copy link
Contributor

I don't think this is something we're going to address until 1.0, since all the $stateChange* events are being deprecated.

@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
Projects
None yet
Development

No branches or pull requests

4 participants