Skip to content

Redirect within Resolve from Angular to AngularJS router breaks in some cases #17023

Closed

Description

@jasonaden

We’ve got a situation where in a Resolver, users may want to redirect to an AngularJS route (or any URL not handled by the Angular router). This works okay when you first click on the route as it falls into an else if clause in executeScheduledNavigation designed to clean up the currently rendered route. runNavigate is then run and AngularJS router ends up taking over.

But if you cmd+click (or deep link) to this same route, you end up going to / route every time, assuming Angular Router is not set up to handle the / route. This happens because / is the default rawUrlTree when router is instantiated, and Angular Router won’t know about this route.

Here's an example reproducing the issue. If you click on Settings and then Page Size Settings, you will be redirected to /messages/inbox. But if you cmd+click you will be redirected to /.

Activity

  1. self-assigned this
    on May 25, 2017
  2. jasonaden commented on May 31, 2017

    @jasonaden
    ContributorAuthor

    As it turns out, adding "/" to the conditions of UrlHandlingStrategy.shouldProcessUrl will make the above scenario work.

    What's happening on clicking a link that's redirected in a resolve is the router sees the new URL being linked to and finds it doesn't handle that URL. It looks and sees that the previous URL was handled by the Angular router so it goes into "cleanup" mode. It then lets that URL through and it gets handled by the AngularJS router.

    In direct-link mode, the Angular router sees it doesn't handle the link and looks for the previously successfully rendered route. There isn't one so it defaults to root (or /). It also finds it doesn't handle this route so redirects to /.

    Therefore, adding / to the list of URLs handled by the Angular router will trick Angular router into going down the "working" code path.

    However, this is not a perfect solution as the history managed by the Angular router is incorrect (note that browser history is correct, so browser back buttons work as intended). The Angular router history ends up with a navigation to / in both cases, meaning a link such as <a routerLink="../">Back</a> will always land back at /.

  3. jasonaden commented on May 31, 2017

    @jasonaden
    ContributorAuthor

    An implementation of the above can be found here. Note there is a new directory on this branch called empty with an empty route configured. This was an attempt to address this problem using a "sink route" as per the description in this article, but this did not seem to address the problem.

  4. jasonaden commented on Sep 15, 2017

    @jasonaden
    ContributorAuthor

    A possibility would be to let the Angular Router handle the initial page that was loaded. In other words, right now we have an issue because we are routing to an ng2 route, then in a Guard we are redirecting to an ng1 route. The router tries to "clean up" and looks to see the last successful navigation. Because we are deep linking, there isn't one and the default is used (/).

    What if the default were the route first routed to. Or maybe don't have a default and don't do this cleanup step if there's no default.

    Needs to be tested. Noting here to track possible solutions.

  5. jasonaden commented on Sep 15, 2017

    @jasonaden
    ContributorAuthor

    Further review seems to indicate that redirecting from an ng2 route to another ng2 route doesn't work. The router falls into the same if condition mentioned above, but on redirect tries to just re-navigate. State seems to get messed up in this case and the redirect fails (and user lands on / root page).

    Note that there's another difference between the ng2 and ng1 version of the redirect. When redirecting from ng2 to ng1 after previously successfully rendering an ng2 route, the redirect will work. When redirecting from ng2 to ng2 route after previously successfully rendering an ng2 route, the redirect will fail and will go back to the last successfully rendered ng2 route.

    Both instances above will redirect to root on a deep link.

  6. jasonaden commented on Sep 15, 2017

    @jasonaden
    ContributorAuthor

    A part of the fix here should be to add the ability to cancel the current navigation. This should "rollback" to a default-like state, then start the new navigation (if redirecting).

  7. added this to the Backlog milestone on Jan 23, 2018
  8. atscott commented on Jul 14, 2020

    @atscott
    Contributor

    Closing, as this seems to have been fixed at some point. I update to the latest versions of both AngularJS and Angular, and followed the steps to reproduce:

    If you click on Settings and then Page Size Settings, you will be redirected to /messages/inbox. But if you cmd+click you will be redirected to /.

    cmd+click navigated to /messages/inbox

    https://github.com/atscott/angularbugrepros/tree/ng1ng2router_redirect_to_ng1

  9. angular-automatic-lock-bot commented on Aug 14, 2020

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  10. locked and limited conversation to collaborators on Aug 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions