Reputation: 1345
I have an angular 6 data service that sets up an observable that is to be shared with at least one component.
I have tried to follow along with the design patterns that are out there for this type of feature.
The problem is that while my component seems to receive the default value, it never updates the data.
The data service looks like this:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, BehaviorSubject, Subscription, fromEvent } from 'rxjs';
@Injectable()
export class CustomerDataService {
dataURL = 'assets/data/customer_sim_data_rollup.json';
private customerData = new BehaviorSubject([{"product": "init1", "revenue": 1, "yearmo": 201801}, {"product": "init2", "revenue": 1, "yearmo": 201801}]);
currentCustData = this.customerData.asObservable()
// private currentCustData = new Observable();
constructor(private http: HttpClient) {
console.log('customer-data-service was called...');
this.getData();
}
getData(yearmo: string): void {
console.log('getData was called...');
this.http.get(this.dataURL).subscribe(data => this.updateData(data)));
}
filterData(data: any, yearmo: string): any[]{
return data.filter(d => d['yearmo'] === yearmo);
}
updateData(data: any): void{
data = this.filterData(data, '201801')
this.customerData.next(data);
}
}
and the component looks like:
import { Component, OnInit, NgModule, OnChanges, SimpleChanges, Input } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule} from '@angular/platform-browser/animations';
import { CustomerDataService } from '../services/customer-data.service';
import { NgxEchartsModule } from 'ngx-echarts';
@Component({
selector: 'app-treemap',
templateUrl: './treemap.component.html',
styleUrls: ['./treemap.component.css']
})
export class TreemapComponent implements OnInit {
@Input() data: any[];
results: any[];
constructor(private custDataService: CustomerDataService) { }
ngOnInit() {
this.custDataService.currentCustData.subscribe(data => this.data = data; console.log(this.data););
this.custDataService.getData('201802');
}
ngOnChanges(changes: SimpleChanges): void {
if( changes['data'] ){
console.log('the data changed')
this.results = this.parseData(this.data);
}
}
parseData(data): any[] {
let parsedData = data.forEach(d => {"name": d["products"], "value": d["revenue"]});
return parsedData;
}
}
@NgModule({
imports:[
NgxEchartsModule,
],
})
export class AppModule { }
The component subscribes to the observable in the service, and then calls this.custDataService.getData('201802');
. I would expect this to both update the service and trigger ngOnChanges
but neither seems to happen.
The console output looks like this:
What have I done wrong?
Upvotes: 1
Views: 3729
Reputation: 4517
Behaviour is correct. ngOnChanges won't trigger when you update variable within the same component. All you need to do is call parseData method inside your subscribe and it will work
this.custDataService.currentCustData.subscribe(data => {
this.data = data;
console.log(this.data);
this.results = this.parseData(this.data);
});
Note: When you pass data from template while including app-treemap component then ngOnChanges will trigger
<app-treemap [data]="someData"></app-treemap> //this will trigger onChange event
Also inside your subscribe you are already getting the data, hence no need to depend on change detection
Upvotes: 1