Search code examples
javascriptangulartypescriptrouter-outlet

shared service didn't update data to parent component angular


hello i am new in angular 5, i have a shared service provided in appmodule, this is the service

import { DetailTransaksi } from '../models/DetailTransaksiModel'
@Injectable()
export class TransaksiService {

  UserTrans:Transaksi;

  constructor() {
    this.UserTrans = new Transaksi();
  }

  getTransaksi(){
    return this.UserTrans;
  }

  addDetail(data:DetailTransaksi){
    this.UserTrans.ListDetail.push(data);
  }

  countDetail(){
    return this.UserTrans.ListDetail.length;
  }

}

the child component is within router-outlet, then in child component i called addDetail() method, but the parent component which is app.component didn't update when i call countDetail, this is my parent component

import { Component, OnInit } from '@angular/core';
import { TransaksiService } from './services/transaksi.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  numPesanan:number;

  constructor(private transService:TransaksiService){
  }

  ngOnInit(){
    this.numPesanan = this.transService.countDetail();

  }
}

Solution

  • The problem is, your ngOnInit() will run only once and the code this.numPesanan = this.transService.countDetail(); will only be run once. There could be two ways in which you update the parent.

    1. Do something on parent so that the countDetail() of the service is run again. For example, upon a button click, call that method of the service.
    2. Make the parent listen to the changes in service.

    In your service, make a variable:

    // private makes it to update only within the service.
    private listLength = new Subject<Number>();
    // public variable will be used to only observe the changes
    listLengthObservable = this.listLength.asObservable();
    
    addDetail(data:DetailTransaksi){
        this.UserTrans.ListDetail.push(data);
        this.listLength.next(this.countDetail());
    }
    

    In the parent component:

    this.transService.listLengthObservable.subscribe((updatedLength) => {
        this.numPesanan = updatedLength
    })