Sledge
Sledge

Reputation: 1345

How to update component data w angular 6 service

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:

enter image description here

What have I done wrong?

Upvotes: 1

Views: 3729

Answers (1)

Pratap A.K
Pratap A.K

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

Related Questions