I'm trying to make a module with components that share a service. One component (graphview) has a subscription to an observable of a BehaviorSubject. Another component (chart-type) later updates the BehaviorSubject by calling a function in the service (chart-config). The problem is when ChartTypeComponent
has the service call .next(data)
the GraphviewComponent
doesn't update. I'm assuming that multiple instances of the service are being used, and I'm not sure how to fix it.
GraphModule
(their parent module) has ChartTypeComponent
and GraphviewComponent
in declarations and has ChartConfigService
in providers.
chart-config.service.ts looks like:
@Injectable()
export class ChartConfigService {
private _chartconfig: BehaviorSubject<any> = new BehaviorSubject<any>({});
public chartconfig = this._chartconfig.asObservable();
private headers = new Headers({ 'Content-Type': 'application/json', 'charset': 'UTF-8' });
private options = new RequestOptions({ headers: this.headers });
constructor(private http: Http) {
http.get('/api/chartconfig/59484e3946f7f059f1e72927')
.map(res => res.json())
.subscribe( data => this._chartconfig.next(data) );
}
getChartConfig(): Observable<any> {
return this.chartconfig;
}
updateChartConfig(option, params) {
this.http.put('/api/chartconfig/59484e3946f7f059f1e72927', '{ ' + JSON.stringify(option) + ': ' + JSON.stringify(params) + ' }' , this.options)
.map(res => res.json())
.subscribe( data => this._chartconfig.next(data) );
}
The graphview.component.ts imports the service and subscription. It doesn't provide the service.
@Component({
selector: 'app-graphview',
templateUrl: './graphview.component.html',
styleUrls: ['./graphview.component.scss']
})
and
constructor(private chartconfigService: ChartConfigService) { }
ngOnInit() {
this.subscription = this.chartconfigService.chartconfig
.subscribe( data => this.localChartConfig = data );
}
the chart-type.component.ts imports the service only, and calls the chartconfigService.updateChartConfig:
@Component({
selector: 'app-chart-type',
templateUrl: './chart-type.component.html',
styleUrls: ['./chart-type.component.scss']
})
and
chartType(param: string) {
this.chartconfigService.updateChartConfig('type', param);
}
I've found relevant questions and answers:
Delegation: EventEmitter or Observable in Angular2
Angular2 Observable BehaviorSubject service not working
but I can't figure out what I'm doing wrong. How can I get graphview.component.ts to update when the updateChartConfig is called?
note: All the call/methods/etc work, and after updateChartConfig() is called this._chartconfig.next(data).getValue()
shows that the BehaviorSubject is being updated properly within the service. The graphview.component.ts simply isn't receiving the new data.
Update:
Results of changing GraphviewComponent
s ngOnInit() to
ngOnInit() {
this.subscription = this.chartconfigService.chartconfig
.subscribe( data => { this.localChartConfig = data; console.log('in subscription: ' + this.localChartConfig); }, e => console.log('error: ' + e), () => console.log('then: ' + this.localChartConfig) );
}
Produces in console:
in subscription: [object Object]
in subscription: [object Object]
But is never proc'd after OnInit (when ChartTypeComponent
calls updateChartConfig() ).
Update2:
It's clear the root is injecting the service, and not the GraphModule:
I'd still like the submodule to provide the service so that it's contained within the submodule.