My goal is to send data from a routed child to the parent. I want to get the reference of a variable from the child, which is nested within a child to the parent through second
One from many outlets to the problem is to use events , load an event emitter to your shared service public onChange: EventEmitter<string> = new EventEmitter<string>();
then brodcast it from the parent to its children, or counterwise, like this
changeMessage(message: string) {
this.currentMessage = of(message)
this.onChange.emit(message);
}
In each occurence when a desired component you want it to join the communicative hive, add an event catcher from this service: this.myService.onChange.subscribe(message=> this.message = message);
This way you could implement an "outward" but complete functional approach to share data at real time between routes.
see this sample. Or you can see this slightly different implementation that merges sibling components and routes.
Or you can use idiosyncratic route parameters
By this way you wouldn't allow any foreign component from another coexistant hierarchy to interfer in these inner messages exchanged between a defined module of routes, because you are underhandedly passing them inbetween.
You would configure the module this way:
export const routes: Routes = [
{ path: '', redirectTo: 'component-one/:message', pathMatch: 'full' },
{ path: 'component-one/:message', component: ComponentOne },
{ path: 'component-two/:message', component: ComponentTwo,
children: [
{ path: '', redirectTo: 'child-one', pathMatch: 'full' },
{ path: 'child-one/:message', component: ChildOne },
{ path: 'child-two/:message', component: ChildTwo }
]
}
];
So that each call to one of those filiations accompanies some parameter to be used in the component html core of which.
In the following example, I made the parameter in function call optional to tell if it was triggered from a component load, thus regenerated, neverthless it originates from a button click, hence just updated respectively to some custom parts.
newMessage(param?) {
if(typeof(param) === 'undefined')
this.message = "Parent";
else
this.message = param;
var actualroute=this.router.routerState.snapshot._root.children[0].children[0].value.url[0].path;
this.router.navigate(['/component-two', this.message , actualroute, this.message ],{relativeTo: this.route});
}
You can see it all working here. Thank you for this fun-challenge.
Weak spot: At each update of the variable message
, the router proceeds to navigate all over again to the same hierarchy which costs time especially for bigger implementations.
Strong point: When you call a router.navigate
there is ability to pass custom data between components, say 'mesage1' for a child and 'message2' for a parent in one row: this.router.navigate(['/component-two', 'message2' , 'child-one', 'message1']);
. This can be done but very complicatedly and condition-entangledly using a service.