sanjeev u rao
sanjeev u rao

Reputation: 103

Understanding ngOnInit

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?

Upvotes: 2

Views: 770

Answers (3)

Aviso
Aviso

Reputation: 695

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.

Upvotes: 1

ShamPooSham
ShamPooSham

Reputation: 2379

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;
      }
    )

Upvotes: 0

Shafeeq Mohammed
Shafeeq Mohammed

Reputation: 1298

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> )

Upvotes: 0

Related Questions