2

I am doing a udemy course on angular and came across this code. I have a sample project which has a Add item button which adds a new item in the array and displays the updated array on screen.

shopping-edit.component.ts

export class ShoppingEditComponent implements OnInit {

  @Input() ingredientsArray : Ingredient[];

  shoppingItemName : string = 'Test';
  shoppingItemAmount : number = 66;

  constructor(private shoppingListService : ShoppingListService) { }

  ngOnInit() {
  }

  onItemAdd(){
    console.log(this.shoppingItemName)
    this.shoppingListService.addIngredient(this.shoppingItemName, this.shoppingItemAmount);
  }

}

I have an event emitter which emits the updated array when the "add" button is clicked.

shopping-list.service.ts

ingredientsChanged = new EventEmitter<Ingredient[]>();

addIngredient(name: string, value : number){
  this.ingredients.push(new Ingredient(name, value));
  this.ingredientsChanged.emit(this.ingredients.slice());
} 

To display the list, I am using shopping-list.component.ts


export class ShoppingListComponent implements OnInit {

  constructor(private shoppingListService : ShoppingListService){}

  ingredients : Ingredient[];


  ngOnInit() {
    this.ingredients = this.shoppingListService.getIngredients();
    this.shoppingListService.ingredientsChanged.subscribe(
      (ingredients : Ingredient[]) => {
        this.ingredients = ingredients;
      }
    )
    console.log("hello")
  }

}

Since ngOnInit() of shopping-list.component.ts runs only once, how is the updated list getting displayed every time the "add" button is clicked?

Lahiru Mirihagoda
  • 1,113
  • 1
  • 16
  • 30
sanjeev u rao
  • 93
  • 1
  • 1
  • 4
  • 1
    This is because of [observables](https://angular.io/guide/observables). I won't make an answer because I would only parrot the documentation, but this is a critical part of Angular, I suggest you to at least read the Angular doc about it to understand the basics ! –  Sep 30 '19 at 09:11
  • As long you have an active subscription to the ingredientsChanged observable, the code given to the subscribe method in your component is executed when the value of the observable changes and your component values are updated. – Fussel Sep 30 '19 at 09:14

3 Answers3

1

Your list is not getting updated in the ngOnOInit. You are only subscribing a observable in the ngOnInit. So whenever you receive new data in your subscription you are updating a varible then because of that ngOnChanges is getting fired which will update your view.

Aviso
  • 695
  • 4
  • 12
0

each time you call onItemAdd() you are updating the item which is in service (using this line of code: this.shoppingListService.addIngredient(this.shoppingItemName, this.shoppingItemAmount);)

And the HTML will be displayed using shoppingListService.ingredients (eg:- <div *ngFor="let ingredient of shoppingListService.ingredients > //here you will get individual ingredient </div> )

Shafeeq Mohammed
  • 1,193
  • 17
  • 25
0

This has more to do with how rxjs Observables work than about ngOnInit. Subscriptions listen to events until it has been unsubscribed. If you only want it to take the first element, you should do this:

this.shoppingListService.ingredientsChanged.pipe(take(1)).subscribe(
      (ingredients : Ingredient[]) => {
        this.ingredients = ingredients;
      }
    )
ShamPooSham
  • 2,301
  • 2
  • 19
  • 28