angular icon indicating copy to clipboard operation
angular copied to clipboard

Allow Route Params to be Passed into Component @Inputs

Open robertdempsey opened this issue 6 years ago β€’ 53 comments

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

When routing to a component, one must inject the ActivatedRoute service to retrieve route data for use inside the component.

Expected behavior

When defining routes, specific params could be used to provide values for @Inputs within the component. For example:

const routes:Routes = [
  {path: '', redirectTo: 'home', pathMatch: 'full'},
  {path: 'home', component: HomeComponent},
  {path: 'search:searchTerm', component: SearchComponent, inputs: { searchTerm: searchTerm }}, // bind the @Input searchTerm from SearchComponent to the searchTerm route parameter
  {path: '**', component: HomeComponent}
];

Minimal reproduction of the problem with instructions

Configure the above routes; specifying data to be passed to component @Inputs is not possible.

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

My team and I are creating completely modular components and publishing them on our private npm repo so that they may be used in any Angular application. We are achieving this modularity through the use of @Inputs, however now we are finding that these are not adequate if wanting to provide data through route/URL parameters.

What we are finding is that now we will have to use either @Inputs or route/URL parameters to provide dynamic data, or use them both in combination but this presents the problem of having to decide which takes precedence if both are present.

This in my opinion breaks the modularity and reusability provided by the @Input functionality that is inherent to components.

Environment


Angular version: 4.3.5


Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

robertdempsey avatar Aug 31 '17 01:08 robertdempsey

Great Idea! - this would be very helpful when building modular components

markwiggles avatar Aug 31 '17 01:08 markwiggles

+1

elliotjr avatar Aug 31 '17 01:08 elliotjr

https://github.com/angular/angular/issues/4452

ericmartinezr avatar Aug 31 '17 08:08 ericmartinezr

We are looking at something similar, but for now I'll close as a duplicate of #4452. Something like this will be coming (ability to bind to @Input properties), but we're not sure what form that will take at the moment.

jasonaden avatar Dec 05 '17 23:12 jasonaden

Thanks for the update @jasonaden. Looking forward to this being implemented so that we can do away with superfluous wrapper components.

Cheers, Rob

robertdempsey avatar Dec 06 '17 09:12 robertdempsey

Any update on this? Thanks!

daniel-upzzle avatar Feb 27 '18 11:02 daniel-upzzle

Hi @jasonaden - #4452 is closed. Is there an open item that can be tracked? Or maybe this was implemented? Thanks πŸ™!

spottedmahn avatar May 24 '18 19:05 spottedmahn

Could we have this issue reopened or linked to an open issue providing the requested functionality, since it is expected to be in the pipeline as per @jasonaden ?

ShadowOfLies avatar Jul 06 '18 08:07 ShadowOfLies

It's a real need, this will allow to separate component and routing concerns. This feature exists in vue router : https://router.vuejs.org/guide/essentials/passing-props.html#boolean-mode

Reeska avatar Jul 11 '18 09:07 Reeska

This feature exists in UI Router as well :

  • AngularJS : https://ui-router.github.io/guide/ng1/route-to-component#resolve-bindings
  • Angular : https://ui-router.github.io/ng2/docs/latest/interfaces/state.statedeclaration.html

Reeska avatar Jul 11 '18 10:07 Reeska

I'm trying to do the same but I got into this issue. This is really needed for creating modular components.

HMubaireek avatar Jul 25 '18 09:07 HMubaireek

+1

autumnfjeld avatar Oct 10 '18 01:10 autumnfjeld

+1

IsharaMS avatar Oct 25 '18 09:10 IsharaMS

+1

drewpayment avatar Nov 05 '18 14:11 drewpayment

Need this feature.. please consider....

debonil avatar Nov 21 '18 08:11 debonil

Why has this request been closed? It was very necessary.

sky10p avatar Dec 10 '18 16:12 sky10p

This was earlier closed as a duplicate, but it looks like that early issue was closed as well. I'll re-open this issue so we can track it here.

We do want to implement something like this. It's unfortunately not the highest priority right now. The earliest we can get to it would be some time in February.

jasonaden avatar Dec 12 '18 00:12 jasonaden

It looks like the Route interface contains a data property. Could this be the solution we are looking for?

export interface Route {
    path?: string;
    pathMatch?: string;
    matcher?: UrlMatcher;
    component?: Type<any>;
    redirectTo?: string;
    outlet?: string;
    canActivate?: any[];
    canActivateChild?: any[];
    canDeactivate?: any[];
    canLoad?: any[];
    data?: Data;
    resolve?: ResolveData;
    children?: Routes;
    loadChildren?: LoadChildren;
    runGuardsAndResolvers?: RunGuardsAndResolvers;
}
/**
 * @description
 *
 * Represents the static data associated with a particular route.
 *
 * See `Routes` for more details.
 *
 * @publicApi
 */
export declare type Data = {
    [name: string]: any;
};

westandy-dcp avatar Jan 15 '19 22:01 westandy-dcp

The route data is already accessible via the ActivatedRoute, but the requestor is proposing that route parameters have the ability to inject through a component's inputs instead.

drewpayment avatar Jan 15 '19 22:01 drewpayment

Quick update: Looks like anything along this type of functionality would be some time after version 8. That being said, providing better APIs such as this is something we want to get to soon after version 8 lands so they can come in later releases such as 8.1 or 8.x releases.

jasonaden avatar Jan 16 '19 00:01 jasonaden

Thanks a lot for the update @jasonaden

robertdempsey avatar Jan 16 '19 05:01 robertdempsey

I am waiting. This will be perfect to use.

leonardovff avatar Jul 09 '19 15:07 leonardovff

any update on this ?

essaidim avatar Aug 26 '19 15:08 essaidim

I thought this was already resolved? :( Is this feature still up to date?

suppadeliux avatar Sep 18 '19 16:09 suppadeliux

What's the progress on this, Angular 9.0 is already in beta, this feature was said to be done in 8+ :(

garg10may avatar Dec 18 '19 15:12 garg10may

Would love to see this feature implemented soon. Any progress?

AvrahamYBock avatar Feb 09 '20 22:02 AvrahamYBock

Any progress?

petriadrian avatar Feb 15 '20 12:02 petriadrian

Pretty please? Hope to see this on the close future roadmap. Would make it alot easier handle data input. Merely for avoiding injecting Route/RouteSnapshot and searching for data it would be worth it.

jbjhjm avatar Feb 19 '20 10:02 jbjhjm

Over a year since this issue has had any serious attention. Is there a workaround for this feature?

deefactorial avatar Mar 09 '20 16:03 deefactorial

We've actually outgrown this feature request, as we now use Resolvers to set data on a common service and then input the data into our components via a wrapper component.

It's a 'workaround' if you will but it took the core of a custom framework to achieve and ended up being a lot more than simply passing static string values from route params into components.

I still think it would be a nice feature though, that and passing route and resolved data directly into component inputs.

robertdempsey avatar Mar 09 '20 21:03 robertdempsey

It's sad to hear :(. Me and my team have been waiting so long to implement this. Our project continues to grow, and for us, this feature is clearly the best choice. Especially when we are trying to do component testing and keep the modularity of each part of our application.

Can you provide and/or someone else an appropriate example of using a Resolver and wrapper component to work around this problem?

Thank you for your help!

suppadeliux avatar Apr 16 '20 15:04 suppadeliux

Hi @suppadeliux,

I'm currently writing up an article which details our journey from before asking for ths feature, to needing this feature, to creating the wrapper component etc.

It'll include a link to the source code and an interactive example using stackblitz. I should have it done in a few days and I'll link it here for you when it's finished.

robertdempsey avatar Apr 16 '20 18:04 robertdempsey

Hi everyone. I wanted this feature for a long time and decided to write it my own npm package for it. It can be not perfect and this is one of my first npm packages, but for my project it is working ok (by now). Currently working only with angular 9 I will appreciate your opinion and any comments: stackblitz: https://stackblitz.com/edit/angular-v8hdug?embed=1&file=src/app/user/user-routing.module.ts npm lib: https://www.npmjs.com/package/ngx-route-params-input

It is using additional wrapper component, which is rendering the passed component and all data from routing as its @Input():

const routes: Routes = [{
  path: ':userId',
  component: NgxRouteParamsInputComponent,
  data: {
    component: UserComponent,
    routeParams: {
      userId: 'userIdInput'
    },
    queryParams: {
      content: 'content'
    }
  }
}];

ndr avatar Apr 19 '20 14:04 ndr

Hi @suppadeliux,

I'm currently writing up an article which details our journey from before asking for ths feature, to needing this feature, to creating the wrapper component etc.

It'll include a link to the source code and an interactive example using stackblitz. I should have it done in a few days and I'll link it here for you when it's finished.

@robertdempsey , Thanks for answering. That would be awesome! Looking forward for it.

suppadeliux avatar Apr 20 '20 08:04 suppadeliux

@suppadeliux no worries. I'm working on it. But for now, it's quite similar to @ndr 's solution. so you may want to check that out. https://github.com/ndr/ngx-route-params-input

Nice work @ndr :)

Haven't had a chance to have a good look yet, but the only thing I'd suggest is trying to strongly type this interface:

export interface IRouteParamsComponentData { component: any; routeParams?: any; // I'd like to make this a mapped type to the component's properties, i.e. { [key: string]: keyof this.component } (pseudo code only, i'm struggling with the same problem) queryParams?: any; [key: string]: any; }

robertdempsey avatar Apr 20 '20 10:04 robertdempsey

@robertdempsey I have never used keyof before, but seems we cannot link it to "this" property inside of interface (since interface is not js construction) and I am getting such error:

A 'this' type is available only in a non-static member of a class or interface

Or maybe I haven't understood your point correctly. In additional or instead, I am thinking of adding the warning (or error) message in case user are trying to pass the property which not exists in the component

ndr avatar Apr 20 '20 11:04 ndr

Yeah, that was just pseudo-code that I wrote. I was struggling with the proper real code, but I've just figured out how to do it with generics. I'll show it to you when I finish my article.

Basically what I meant was that it would be good for a compile time error to be thrown if the property doesn't exist on the component.

On Mon., 20 Apr. 2020, 9:44 pm Andrii Cherepovskyi, < [email protected]> wrote:

@robertdempsey https://github.com/robertdempsey I have never used keyof before, but seems we cannot link it to "this" property inside of interface (since interface is not js construction) and I am getting such error:

A 'this' type is available only in a non-static member of a class or interface

Or maybe I haven't understood your point correctly. In additional or instead, I am thinking of adding the warning (or error) message in case user are trying to pass the property which not exists in the component

β€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/angular/angular/issues/18967#issuecomment-616498917, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFDDBUHAH65GWQJOMB7OWF3RNQYTBANCNFSM4DZAVTOQ .

robertdempsey avatar Apr 20 '20 11:04 robertdempsey

Hey @ndr , nice work! and thanks for sharing.

suppadeliux avatar Apr 21 '20 08:04 suppadeliux

Hi @suppadeliux, @ndr ,

Sorry it took a little longer than I expected, but here it is:

https://medium.com/swlh/a-better-way-to-pass-data-to-your-angular-components-e8b5ef6a642a?source=friends_link&sk=57aa462301a88273e78442fb06d653a1

It's not exactly what you were after @suppadeliux, but it might give you some ideas.

robertdempsey avatar Apr 28 '20 10:04 robertdempsey

it's necessary, hope for it!

Alcantara6 avatar Jun 13 '20 05:06 Alcantara6

I was also searching for this functionality! UP.

GaetanoPiazzolla avatar Sep 18 '20 09:09 GaetanoPiazzolla

It's annoying this is still required. I took a look at the angular source in search of possible "attack points" to use to implement this without help of the official team.

Custom decorators are powerful but I do not see a solution to get the ActivatedRoute if it was not injected in the component (and so it does again require configuration overhead).

Other idea is to modify the logic which creates a routed component. The RouterOutlet component is responsible for resolving and creating the routed Component. It has an injected ComponentFactoryResolver, finds the responsible ComponentFactory and passes the data to Location.createComponent. As almost everything is private in there, there's hardly a solution to modify anything in there. If I find some time, I'll do some experimentation based on custom RouterOutlet and ComponentFactory.

jbjhjm avatar Sep 21 '20 08:09 jbjhjm

@jbjhjm Are you working on this? I a willing to help out if needed.

Remco75 avatar Nov 19 '20 11:11 Remco75

is there ANY update from the team? Is there an expected start of development? This is an extremely useful request. It decouples components from the router. No need to inject the activated route , but simply using inputs. Keeps the components simple and testable, a practice promoted by the angular team.

Also the feature exists in uiRouter where it maps resolves to inputs. I'm Using that in several other projects, but would like to use angular router since that is more actively maintained.

Remco75 avatar Nov 20 '20 08:11 Remco75

@Remco75 unfortunately I am not as I need to prioritize other tasks. Would involve lots of experimental work while it shouldn't be too difficult to add the feature to the router source. I'm not sure what're the current priorities of the angular team, there are lots of important issues and improvements open for long time without much reactions. I hope they will soon begin to focus on such things again.

jbjhjm avatar Nov 24 '20 18:11 jbjhjm

I should not be writing this, but. It's so frustrating that the official angular team does not pay any attention to features that are so obvious, so desired, (seemingly) easy to implement, but yet waited for for 3.5 years.

Maximaximum avatar Apr 06 '21 10:04 Maximaximum

I also need this... Any updates?

L96Github avatar Jul 02 '21 14:07 L96Github

Still nothing... 😭😭😭

suppadeliux avatar Jul 02 '21 14:07 suppadeliux

Any updates? We really need this in our project 😒

Samoji avatar Jul 19 '21 11:07 Samoji

Hi guys, I finally had time to write a small Angular library that overcomes these downsides of the Angular router. It allows you to pass route params (path and query params) to component inputs by simple configuration. Optionally it can do even more: It lets you adjust these url params on component output changes. So basically you can "two-way databind" your component fields to router path/query params.

demo

demo

npm: https://www.npmjs.com/package/@jdrks/ngx-deep-linking github project: https://github.com/Nas3nmann/ngx-deep-linking

Nas3nmann avatar Jul 25 '21 16:07 Nas3nmann

So...any updates on this one? :D

Ferranteg-dev avatar Feb 15 '22 12:02 Ferranteg-dev

any updates here ?

ajlif avatar May 25 '22 15:05 ajlif

It will be a real help.. i am waiting. i am new to Angular, and i thought there is a feature like this.

RandAldurayhim avatar Aug 03 '22 11:08 RandAldurayhim

With the new component creation apis, this feature would be easier to implement.

eneajaho avatar Aug 03 '22 16:08 eneajaho

With the new component creation apis, this feature would be easier to implement.

This is correct, but more specifically this PR in particular: feat(core): add ability to set inputs on ComponentRef. We plan on revisiting this feature in the near future.

atscott avatar Aug 03 '22 17:08 atscott