angular
angular copied to clipboard
Allow Route Params to be Passed into Component @Inputs
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:
Great Idea! - this would be very helpful when building modular components
+1
https://github.com/angular/angular/issues/4452
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.
Thanks for the update @jasonaden. Looking forward to this being implemented so that we can do away with superfluous wrapper components.
Cheers, Rob
Any update on this? Thanks!
Hi @jasonaden - #4452 is closed. Is there an open item that can be tracked? Or maybe this was implemented? Thanks π!
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 ?
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
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
I'm trying to do the same but I got into this issue. This is really needed for creating modular components.
+1
+1
+1
Need this feature.. please consider....
Why has this request been closed? It was very necessary.
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.
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;
};
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.
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.
Thanks a lot for the update @jasonaden
I am waiting. This will be perfect to use.
any update on this ?
I thought this was already resolved? :( Is this feature still up to date?
What's the progress on this, Angular 9.0 is already in beta, this feature was said to be done in 8+ :(
Would love to see this feature implemented soon. Any progress?
Any progress?
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.
Over a year since this issue has had any serious attention. Is there a workaround for this feature?
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.
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!
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.
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'
}
}
}];
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 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 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
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 .
Hey @ndr , nice work! and thanks for sharing.
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.
it's necessary, hope for itοΌ
I was also searching for this functionality! UP.
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 Are you working on this? I a willing to help out if needed.
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 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.
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.
I also need this... Any updates?
Still nothing... πππ
Any updates? We really need this in our project π’
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.
npm: https://www.npmjs.com/package/@jdrks/ngx-deep-linking github project: https://github.com/Nas3nmann/ngx-deep-linking
So...any updates on this one? :D
any updates here ?
It will be a real help.. i am waiting. i am new to Angular, and i thought there is a feature like this.
With the new component creation apis, this feature would be easier to implement.
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.