Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular strict strictPropertyInitialization - where to init member?

During the initialization of a component I want to retrieve some user information. Now, with the Angular strict mode, I'm not sure where to load this data?

I can think of 3 options. But which is the correct one? Or is there another possibility?

#1 in this option the service method will be called directly on initialization of the userInfo.

export class NavComponent implements OnInit {
  public userInfo$: Observable<LoggedInUser> = this.sessionService.getUserInformation();

  constructor(private sessionService: SessionService) {}

  ngOnInit(): void {}
}

#2 In my opinion it will be better to source this into the constructor like so:

export class NavComponent implements OnInit {
  public isMobileMenuCollapsed = true;
  public userInfo$: Observable<LoggedInUser>;

  constructor(private sessionService: SessionService) {
    this.userInfo$ = this.sessionService.getUserInformation();
  }

  ngOnInit(): void {}
}

#3 in the ngOnInit-method instead of the constructor. But for this solution I need the Definite Assignment Assertion as well:

export class NavComponent implements OnInit {
  public isMobileMenuCollapsed = true;
  public userInfo$!: Observable<LoggedInUser>;

  constructor(private sessionService: SessionService) {
  }

ngOnInit(): void {
  this.userInfo$ = this.sessionService.getUserInformation();
}

}

Which of this possibilties should I use in my code?

like image 591
user2622344 Avatar asked Mar 01 '23 17:03

user2622344


2 Answers

TL;DR use option #1.

Which one is correct?

Are you using userInfo$ only in your HTML template? Then all of the three options should work in theory.

Why?

Because template code runs after ngOnInit, so userInfo$ should have been initialized by then in all three options.

Which one is better?

#1 and #2 is essentially same, in both cases, userInfo$ is getting initialized in constructor. I prefer #1 as it removes redundancy in code.

#3 is slightly different as the initialization is not happening in constructor. So this may introduce some subtle bugs if you use userInfo$ inside the component (for example, in ngOnChanges which gets called before ngOnInit).

like image 136
Md Enzam Hossain Avatar answered Jun 05 '23 06:06

Md Enzam Hossain


What is you real problem? I guess it is about a mismatch of types in your template while using the async pipe?

You need to know the async pipe may return null the mismatch is not with you observable but with the result of the pipe.

How to fix it?

Well, introduce a *ngIf on the element or on an element on higher level and use the result. Because of the *ngIf the data type cannot contain null anymore

<ng-container *ngIf="data$ | async as data">

like image 31
Thomas Renger Avatar answered Jun 05 '23 04:06

Thomas Renger