In one of my Angular 2 routes's templates (FirstComponent) I have a button
first.component.html
<div class="button" click="routeWithData()">Pass data and route</div>
My goal is to achieve:
Button click -> route to another component while preserving data and without using the other component as a directive.
This is what I tried...
1ST APPROACH
In the same view I am storing collecting same data based on user interaction.
first.component.ts
export class FirstComponent {
constructor(private _router: Router) { }
property1: number;
property2: string;
property3: TypeXY; // this a class, not a primitive type
// here some class methods set the properties above
// DOM events
routeWithData(){
// here route
}
}
Normally I'd route to SecondComponent by
this._router.navigate(['SecondComponent']);
eventually passing the data by
this._router.navigate(['SecondComponent', {p1: this.property1, p2: property2 }]);
whereas the definition of the link with parameters would be
@RouteConfig([
// ...
{ path: '/SecondComponent/:p1:p2', name: 'SecondComponent', component: SecondComponent}
)]
The issue with this approach is that I guess I can't pass complex data (e.g. an object like property3) in-url;
2ND APPROACH
An alternative would be including SecondComponent as directive in FirstComponent.
<SecondComponent [p3]="property3"></SecondComponent>
However I want to route to that component, not include it!
3RD APPROACH
The most viable solution I see here would be to use a Service (e.g. FirstComponentService) to
- store the data (_firstComponentService.storeData()) on routeWithData() in FirstComponent
- retrieve the data (_firstComponentService.retrieveData()) in ngOnInit() in SecondComponent
While this approach seems perfectly viable, I wonder whether this is the easiest / most elegant way to achieve the goal.
In general I'd like to know whether I'm missing other potential approaches to pass the data between components, particularly with the less possible amount of code
I think since we don't have $rootScope kind of thing in angular 2 as in angular 1.x. We can use angular 2 shared service/class while in ngOnDestroy pass data to service and after routing take the data from the service in ngOnInit function:
Here I am using DataService to share hero object:
Pass object from first page component:
Take object from second page component:
Here is an example: plunker
3rd approach is most common way to share data between components. you may inject the item service which you want to use in related component.
Pass using JSON
Solution with ActiveRoute (if you want pass object by route - use JSON.stringfy/JSON.parse):
Prepare object before sending:
Receive your object in destination component:
use a shared service to store data with a custom index. then send that custom index with queryParam. this approach is more flexible.
.
update 4.0.0
See Angular docs for more details https://angular.io/guide/router#fetch-data-before-navigating
original
Using a service is the way to go. In route params you should only pass data that you want to be reflected in the browser URL bar.
See also https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service
The router shipped with RC.4 re-introduces
data
See also the Plunker at https://github.com/angular/angular/issues/9757#issuecomment-229847781