X Tutup
The Wayback Machine - https://web.archive.org/web/20230414024453/https://github.com/angular/angular/issues/13373
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

Route redirectTo as function / class #13373

Open
stochris opened this issue Dec 10, 2016 · 18 comments
Open

Route redirectTo as function / class #13373

stochris opened this issue Dec 10, 2016 · 18 comments
Assignees
Labels
area: router feature: under consideration Feature request for which voting has completed and the request is now under consideration feature Issue that requests a new feature freq2: medium
Milestone

Comments

@stochris
Copy link

stochris commented Dec 10, 2016

I'm submitting a ... (check one with "x")

[ ] bug report => search github for a similar issue or PR before submitting
[x ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

What is the motivation / use case for changing the behavior?

Currently, in a Route definition, redirectTo can only be a string.In order to provide higher flexibility, it could also be a object, like the Rezolve.
The advantages related to the control we can have over the route parameters and the queryParams, or even dynamic redirection

  • Language: Typescript
@vicb vicb added area: router feature Issue that requests a new feature flag: can be closed? labels Dec 11, 2016
@vicb
Copy link
Contributor

vicb commented Dec 11, 2016

You can redirect in the CanActivate guard, can't you ?

@stochris
Copy link
Author

stochris commented Dec 11, 2016

Yes, and that's the approach I took. However, I feel that mentally separating redirect and guards is a lot more easy to reason about. Also, using the guard approach, the route still needs a component , children or redirectTo defined.

If there would be no problem, I would be open to implementing it using the same pattern as the CanActivate interface

@csvn
Copy link

csvn commented Sep 28, 2017

@vicb canActivate guard for redirects instead of redirectTo does not feel fully supported. The code below will fail with error:

"Invalid configuration of route ''. One of the following must be provided: component, redirectTo, children or loadChildren"

const routes: Routes = [
  { path: '', canActivate: [RedirectGuard] }
];

There is no error when redirectTo and path is used. Adding children: [] works as a workaround, but using "guard" for routing feels a bit weird and clunky sometimes.

I have a bit of advanced use case. The app I'm working on has /:organization/:cluster as parameters. All other routes lie under this route. I would like to have a dynamic redirect from / which uses a UserService to figure out which params to use.

@nicksloan
Copy link

This would also be great for my project as well. In the simplest case, I would be happy to have redirectTo be a function that can take an ActivatedRouteSnapshot and a RouterStateSnapshot as arguments.

I'm using this to support a structure like this:

{
  path: 'topics',
  { topics: TopicsResolver },
  children: [
    {
      path: 'default',
      redirectTo: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
        return ['topics', route.data.topics[0]];
      }
    },
    {
      path: ':topic_id',
      resolve: { topic: TopicResolver },
      component: TopicComponent
    }
  ]
}

We used a structure like this for our AngularJS app with UI-Router, and it worked very well. I would love to be able to mimic that in Angular.

@ngbot ngbot bot added this to the Backlog milestone Jan 23, 2018
@SamVerschueren
Copy link
Contributor

I know this already is quite old. But I'm in the same situation. I want to redirect from an empty route to another route with dynamic params. Now I have to do this

{path: '', pathMatch: 'full', children: [], canActivate: [RedirectGuard]}

Which is a little ugly and looks like I'm abusing the system.

@toverux
Copy link

toverux commented Aug 20, 2019

According to this article, Better Redirects in Angular Route Guards, since Angular 7 it is allowed to return an UrlTree in canActivate.
Still feels weird to do that in something called a "guard" or "can activate", but at least now redirection is properly supported by the framework in guards, and if you read the end of the article, this can neutralize a few potential bug sources.

@somu93
Copy link

somu93 commented Nov 16, 2019

I know this already is quite old. But I'm in the same situation. I want to redirect from an empty route to another route with dynamic params. Now I have to do this

{path: '', pathMatch: 'full', children: [], canActivate: [RedirectGuard]}

Which is a little ugly and looks like I'm abusing the system.
Hey Is there Any Other Solution To Redirect To that Particular Child Route other than Using canActive.
I am facing the same issue and it will happen only when you trying to load a Module lazily when the App starts. Surprisingly it will work fine if we redirect to this lazy-loaded module from some other module through route.navigate['/LazyModule'].

My Code :

app-routing.module.ts :
const routes: Routes = [
{path: 'tracker', loadChildren: () => import(./feature/tracker/tracker.module).then(m => m.TrackerModule)},
{path: '', redirectTo : '/tracker', pathMatch: 'full'}
];

tracker-routing.module.ts :
const routes: Routes = [
{ path: '', component: TrackerComponent, children :
[
{ path: '',pathMatch : 'full' , redirectTo: 'trackercreate'},
{ path: 'trackercreate', component: TrackerCreateComponent },
{ path: 'trackerlist', component: TrackerListComponent },
{ path: '**', redirectTo: 'trackercreate'}
]
}
];

Expected Behaviour When App Loaded for 1st time (URL) :
http://localhost:4200/tracker/trackercreate

Actual Behaviour Now What I am getting for 1st time App Loading (URL): http://localhost:4200/tracker

Can Anyone Please help me to Understand this Concept, like why this is happening and how to resolve this. Thank You very Much. :)

@honzajde
Copy link

Maybe making route.paramMap mutable would be enough:
router:

resolve: {
  dynamicIdOrSomethingElse: DynamicResolver 
}
redirectTo: 'dynamic-path/:dynamicId'

DynamicResolver :

resolve(route: ActivatedRouteSnapshot, ...  

  route.paramMap.set('dynamicId', 123)    
  ...

but route.paramMap.set set is not allowed by paramMap.

atscott added a commit to atscott/angular that referenced this issue Dec 10, 2020
… redirectTo

Redirects in the router are processed before activations. This means that a canActivate will
never execute if a route has a redirect. Rather than silently ignoring
the invalid config, developers should be notified so they know why it
doesn't work.

Closes angular#18605
The feature request for a function/class redirect is covered in angular#13373.
atscott added a commit to atscott/angular that referenced this issue Dec 10, 2020
… redirectTo

Redirects in the router are processed before activations. This means that a canActivate will
never execute if a route has a redirect. Rather than silently ignoring
the invalid config, developers should be notified so they know why it
doesn't work.

Closes angular#18605
The feature request for a function/class redirect is covered in angular#13373.
josephperrott pushed a commit that referenced this issue Jan 5, 2021
… redirectTo (#40067)

Redirects in the router are processed before activations. This means that a canActivate will
never execute if a route has a redirect. Rather than silently ignoring
the invalid config, developers should be notified so they know why it
doesn't work.

Closes #18605
The feature request for a function/class redirect is covered in #13373.

PR Close #40067
@angular-robot angular-robot bot added the feature: under consideration Feature request for which voting has completed and the request is now under consideration label Jun 4, 2021
@egonknapen
Copy link

egonknapen commented Jun 10, 2022

I have been using the solution like @SamVerschueren wrote for years now. But since angular 14 it's not possible to use pathMatch="full" and a dynamic direct function any more without adding a useless component (read unused/dummy).

@dzonatan
Copy link
Contributor

@egonknapen just faced with the same issue but it seems that adding children: [], allows you to avoid that dummy component.

@egonknapen
Copy link

@egonknapen just faced with the same issue but it seems that adding children: [], allows you to avoid that dummy component.

Thanks, I tried using children, but I couldn't imagine what to put in it, didn't think about leaving it just empty. So now we got 2 so called hacks [canActivate] + 'children:[]', to get dynamic routing working.

I would suggest angular comes up with their own solution or add the preferred way to their documentation.

@superole
Copy link
Contributor

superole commented Jul 6, 2022

Thanks, I tried using children, but I couldn't imagine what to put in it, didn't think about leaving it just empty. So now we got 2 so called hacks [canActivate] + 'children:[]', to get dynamic routing working.

Same here. It seems weird that an empty children array passes validation, but leaving children out does not.
As an alternative to canActivate: [RedirectGuard], I'm using resolve: {resolvedData: RedirectResolver}, and in the resolve function I'm using this.router.navigate().

Reading this thread it seems that canActivate has more of a built in redirect feature, but the resolver works well enough for me

@epelc
Copy link
Contributor

epelc commented Aug 24, 2022

Angular v14 makes this more apparent by validating routes in lazy loaded modules. I think a lot more people are going to run into this missing feature with the common workaround of using a guard.

The empty children array workaround is probably more confusing than the error.

image

@egonknapen
Copy link

The empty children array workaround is probably more confusing than the error.

I searched in the internet, and found a few articles all describing the same way. So I think it's up to the angular developers, to add their preferred way. It's a valid use case, to want a dynamic routing. If they don't I'm afraid, next time they will come up with another way to prevent us from doing just that.

Of all the components of angular I have been using, the routing had been the most limiting (read less happy with). For example I wish it was more easy to use matrix variables, even when you don't want navigation to happen, for example if you are using tabs, and want the current tab as a matrix variable, so when copy&pasting the url, it will open on the same page.

(But that's outside the scope of this bug-issue)

@Jakepritchard98
Copy link

I have a scenario where different users have a different landing page after sign in. The default landing page is set in the redirectTo but this now needs to become dynamic to accommodate for the different user types.

For example:

  • Finance user should be directed to the finance dashboard,
  • Driver user should be directed to their jobs page,
  • Admin user should be redirected to a business dashboard

Would be helpful if redirectTo can be structured like canActivate and we can access the ActivatedRouteSnapshot.

@juanmendes
Copy link

juanmendes commented Feb 13, 2023

We have a similar use case when a user goes to /libraries, we want to redirect to one of its children depending on the user's rights. Using the CanActivate guard hack to redirect. Had not thought of using children: [] as I'm updating from ng13->14->15 but it worked, and we were using a resolver which sounds even worse than using a guard.

@epelc I disagree, I used the error message to find this thread as I updated Angular and it was pretty easy.

@egonknapen
Copy link

egonknapen commented Feb 13, 2023

We have a similar use case when a user goes to /libraries, we want to redirect to one of its children depending on the user's rights. Using the CanActivate guard hack to redirect. Had not thought of using children: [] as I'm updating from ng13->14->15 but it worked, and we were using a resolver which sounds even worse than using a guard.

I personally have the opinion that both are only hacks. I better solution would be something like [RedirectTo] with a function/method behind it. So it would be directly clear, that this function would specify the direct.

But as often I get to hear, it's not in the documentation, it's not planned, end of discussion. But then there are hacks to fix what is missing, until the next time, when they close a way around the problem.

We will see, probably need to make a feature request, and then get at least 20 people to vote for it. But for that we need to wait, we only got 15 people now, watching this.

@atscott
Copy link
Contributor

atscott commented Feb 21, 2023

Just a quick update: I do believe this is a high priority item for the Router. There are some questions that I don't have answers to at the moment but don't have time to fully think about due to other items that are higher priority. Maybe discussions in this issue can explore these and come to a satisfactory answer:

  1. Can/should the function return a string that acts like the existing redirects? (probably)
  2. Can/should the function also be able to return a UrlTree that is an absolute redirect? (probably)
  3. The big one: what parameters does the function get? If we're allowing a UrlTree return value, we're going to want better parameters than what you currently get for canMatch guards (route: Route, segments: UrlSegment[] ) so we can update/retain query params, fragment, and/or path params. How do we get that information? Would it be sufficient to answer this question later and initially release the redirect feature without any parameters? Releasing with parameters that aren't helpful wouldn't be good because (1) the aren't helpful and (2) it might require a breaking change to update them in the future. Would an initially parameter-less function still require a breaking change to add parameters later?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: router feature: under consideration Feature request for which voting has completed and the request is now under consideration feature Issue that requests a new feature freq2: medium
Projects
None yet
Development

No branches or pull requests

X Tutup