Reputation: 1310
I have a parent component with two child routes. Each child route will need to use/access the same data retrieved from a GET request.
I think it may be wasteful to query the server each time a child route is loaded, so I thought a good way of doing this would be to query the server once through the parent route and then sharing the data afterwards through a bi-directional service, which I'm trying to implement following the angular docs closely.
However, neither of the child components are able to subscribe to the observer set in the service, and I'm not sure why?
Here are some code snippets;
Parent Component:
@Component({
selector: 'parent',
template: `
<div>
<ul>
<li><a routerLinkActive="active" routerLink="child1">Child1</a></li>
<li><a routerLinkActive="active" routerLink="child2">Child2</a></li>
</ul>
</div>
<router-outlet></router-outlet>
`,
})
export class ParentComponent implements OnInit {
constructor(private testService: TestService) {}
ngOnInit(){
this.testService.getData(this.testService.createProfileData())
}
}
Child Components (they have the same code for now)
export class Child1Component implements OnInit {
public profileData: any;
constructor(private testService: TestService) {}
ngOnInit(){
this.testService.profile$.subscribe((data) => {
console.log(data)
this.profileData = data;
})
}
}
test service:
import { Injectable } from '@angular/core';
import 'rxjs/Rx';
import {Observable} from 'rxjs';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class TestService {
profile = new Subject<any>();
profile$ = this.profile.asObservable();
getData(obj:any) {
console.log(obj)
return this.profile.next(obj);
}
createProfileData(){
return {name:'test-me!'}
}
}
And here is a plunker with all the code:
https://plnkr.co/edit/CCnZbHTzU8R0uKo0WtbD?p=preview
The desired output here would be for the parent component to send a GET
request to the server (demonstrated by creating a simple object here) and then updating profile = new Subject<any>();
inside the service.
Then each time the child routes are called, they would subscribe to this observer through the service and have access to the data without having to query the server each time.
I'm not sure if this is the correct method for achieving such an outcome? and if it is, I'm not sure why it will not work in my example?
I've started to look into other methods that could potentially work, such as ngrx/store
. But I'm not really sure on what the best way to do this is so any advice is really appreciated.
Hope the question is clear, let me know if you need any more information! Thanks
Upvotes: 0
Views: 449
Reputation: 10813
Angular resolver to the rescue !
First, define a routing configuration as below :
{
path: 'parent',
component: ParentComponent,
resolve: {
data: DataResolverService
},
children: [
{
path: 'child1',
component: Child1Component,
},
{
path: 'child2',
component: Child2Component,
}
]
},
where DataResolverService
@Injectable()
export class DataResolverService implements Resolve<any> {
constructor(private testService: TestService) {
}
resolve(route: ActivatedRouteSnapshot): Observable<any> {
return this.testService.getData().first();
}
}
and then in your components :
constructor(private activatedRoute: ActivatedRoute) {
}
ngOnInit() {
this.activatedRoute.parent.data.pluck('data').subscribe((data: any) => {
this.data = data;
});
}
Upvotes: 1