Search code examples
angularngoninit

How the service method is working inside the ngOnInit() even ngOnInit() hook executed once?


This is the code inside of my Angular service....

export class DataService{

     products = {
            'productsList': [
                 {id: 101, name: 'Apple', qty: 2},
                 {id: 102, name: 'Mango', qty: 1},
                 {id: 103, name: 'Grapes', qty: 1},
                 {id: 104, name: 'Banana', qty: 3}
             ]
      };

     constructor() {}

     getProducts(){
          return this.products.productsList;
     }

     addProduct(obj: {id:number, name:string, qty:number}){
         this.products.productsList.push(obj);
     }
 }

and this one is from angular component...

export class AppComponent implements OnInit{
   pId!:number;
   pName!:string;
   pQty!:number;
   pObject!:{id:number, name:string, qty:number};
   pObjectArray:{id:number, name:string, qty:number}[] = [];

   constructor(private dataService: DataService) {};

   ngOnInit(){
       this.pObjectArray = this.dataService.getProducts();
   }

   addProduct(){
       this.pObject = {
       id: this.pId,
       name: this.pName,
       qty: this.pQty
       }
       this.dataService.addProduct(this.pObject);
  }
}

So I just want to know when we will load this component then ngOnIniti() will called once and it will call the getProducts() method from the service class and then we will fetch the data from the service through this method and will assign it to pObjectAray property inside component. which is fine. but now if I add any new product by calling the addProduct() method of component and then this method will call the addProduct() of service so it will update the products object of the service so now products object have 5 new product instead of 4 because we just added the new one. so my question is how the getProducts() inside the ngOnInit executing automatically and updating the pObjectArray property of the component?

I mean ngOnIniti() only called once when we have loaded the component so ngOnInit() will not execute this time and I have already tested it by printing some message using console.log() inside ngOnInit(). So Please explain me how the data is updating automatically in component with every changes. for example if we add new data or delete or modify data then it is automatically updating the pObjectArray with the updated data.

Sorry for my bad english...


Solution

  • That is because of returning the array By reference from the service file. So, whatever changes you do to the array in your service file, will get reflected in the corresponding components that get that array.

    And due to angular's default change detection strategy, you will see the updates in the template or anywhere you use that array.

    If you send a copy of the array, then you don't see the behavior you are facing.

    getProducts() {
      // return this.products.productsList.slice();
      or
      // return [ ...this.products.productsList ];
    }
    

    Check below snippet about how it mutating the array

    var a = [1, 2, 3, 4, 5]
    
    function changeArray(arr) {
      arr.splice(2, 1);
    }
    
    changeArray(a);
    console.log(a);

    Check this stackblitz for how returning the copy of array didn't update the component property