Sep 30, 2020

Angular component field initialization

In my previous post, I talked about Class field initialization in typescript. How about field initialization of angular component, is it different? Angular component is defined an typescript class. It should follow same logics. However, Angular component has life cycle. The ngOnInit is special method that angular will run angular first displays the data-bound properties and sets the directive or component's input properties. So if your initialization code depends on these data-bound proprties and input properties, you can not run them in constructor. So the following code doesn't work

@Component({
  //..
})
class MyComponent {

  //angular specific
  @Input() firstName: string;
  @Input() lastName: string;

  fullName: string;

  constructor() {
    //this does not work
    this.fullName = this.firstName + ',' + this.lastName;
  }
}

You have to run this code in the ngOnInit method like below.

@Component({
  //..
})
class MyComponent {

  //angular specific
  @Input() firstName: string;
  @Input() lastName: string;

  fullName: string;

  ngOnInit() {
    this.fullName = this.firstName + ',' + this.lastName;
  }

}

But some people take it too far. Since it is safter to run in ngOnInit method, why not always put all initialize code in this method. And So the following initialization code become very popular, even the initialization code has no dependency of angular data-bound proprties and input properties.

@Component({
  //..
})
class ProductComponent {

  displayCode$: Observable<boolean>;
  errorMessage$: Observable<string>;
  products$: Observable<Product[]>;
  selectedProduct$: Observable<Product>;

  constructor(private store: Store) { }

  ngOnInit(): void {
    this.store.dispatch(ProductPageActions.loadProducts());
    this.products$ = this.store.select(getProducts);
    this.errorMessage$ = this.store.select(getError);
    this.selectedProduct$ = this.store.select(getCurrentProduct);
    this.displayCode$ = this.store.select(getShowProductCode);
  }
}

So If we understand this, can initialize the code like the following. It saves your effor of explicit typing by using typescript type inference. and it also improves code readability.

@Component({
  //..
})
class ProductComponent {

  products$ = this.store.select(getProducts);
  errorMessage$ = this.store.select(getError);
  selectedProduct$ = this.store.select(getCurrentProduct);
  displayCode$ = this.store.select(getShowProductCode);

  constructor(private store: Store) { }
}

No comments:

Post a Comment