Angular strictPropertyInitialization - best practices for initializing class members?

When initializing a component, I need to retrieve user information. However, with the Angular strict mode in place, I'm uncertain about where to fetch this data.

I have considered 3 options. But which one is the most appropriate? Is there another alternative?

#1 This option involves calling the service method 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 I believe it would be more beneficial to initialize this in the constructor:

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 rather than the constructor. However, for this solution, I also require the Definite Assignment Assertion:

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 these options should I implement in my code?

Answer №1

In short, go with option #1.

Which option is the right one?

If you're exclusively using userInfo$ in your HTML template, then theoretically all three options should work.

Why is that?

Since template code runs after ngOnInit, by then userInfo$ should have already been initialized in all three scenarios.

So, which option is superior?

Both #1 and #2 are essentially the same as they both initialize userInfo$ in the constructor. I find #1 preferable as it eliminates redundancy in the code.

#3 differs slightly as the initialization doesn't occur in the constructor. This could potentially lead to subtle bugs if you end up utilizing userInfo$ within the component (like in ngOnChanges which is invoked before ngOnInit).

Answer №2

Are you facing a real problem? Could it be related to a type mismatch in your template when using the async pipe?

Remember, the async pipe might return null, indicating that the issue lies not with your observable but with the result of the pipe.

How can you resolve this issue?

To address this, consider adding a *ngIf directive on the element or a parent element and utilize the output. By using *ngIf, you ensure that the data type does not contain null anymore.

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Upon the second click, the addEventListener function is triggered

When using the window.addEventListener, I am encountering an issue where it only triggers on the second click. This is happening after I initially click on the li element to view the task information, and then click on the delete button which fires the eve ...

When making Angular GET requests, the response may return a single Object instead of an Array

When making a GET request to my API, the data is returned as Objects inside an Object instead of an Array of Objects. This makes it difficult for me to iterate through and print the data. I am puzzled by why this specific request is behaving differently c ...

Trigger @HostListener event after a certain delay

I am currently working on implementing a basic infinite-scroll directive in Angular2. To achieve this, I am utilizing @HostListener('window:scroll') to capture the scroll event and extract the data from the $target. My concern is that every time ...

Recommendations for Organizing Multiple "Isolated" Applications Using MVC 5 and Angular 2

We are currently managing a large MVC 5 ASP.NET 4.5.1 web application that follows the concept of treating each page as its own application due to the vast areas it covers. The existing pages are built using JQuery, regular Javascript, and Handlebars templ ...

What's the reason behind having to run npm install every time I start a fresh Angular 2 project?

Whenever I start a new Angular 2 project, it keeps displaying the message "node_modules appears empty, you may need to run `npm install`". ...

A method for modifying the key within a nested array object and then outputting the updated array object

Suppose I have an array called arr1 and an object named arr2 containing a nested array called config. If the key in the object from arr1 matches with an id within the nested config and further within the questions array, then replace that key (in the arr1 ...

Importing TypeScript Modules from a Custom Path without Using Relative Paths

If we consider the following directory structure: - functions - functionOne - tsconfig.json - index.ts - package.json - node_modules - layers - layerOne - tsonfig.json - index.ts - index.js (compiled index.ts ...

"NameService is not provided in Angular, please check your module

I've been struggling with loading a class into my Angular component. I've spent quite some time trying to figure out the solution, even attempting to consolidate everything into a single file. Here is what I have: Application.ts /// <referenc ...

Is there a way to update the parent state from a child component in React when using Switch Route?

I have a page that features a control panel for modifying the content on display through Switch-Route. The code structure is as follows: <div className="controls"> some controls here </div> <Switch> <Route exact path=&apo ...

Error encountered when extending Typography variant in TypeScript with Material UI v5: "No overload matches this call"

Currently, I am in the process of setting up a base for an application using Material UI v5 and TypeScript. My goal is to enhance the Material UI theme by adding some custom properties alongside the default ones already available. The configuration in my ...

Creating Personalized Validators for Angular Version 5 Reactive Forms

I am struggling to create a custom validator for my Angular v5 application. I followed the documentation for a basic password match example in the Docs, but it's not working as expected. this.personalInfoForm = _fb.group({ 'name': [null,V ...

Is it more beneficial to convert all the current jQuery AJAX webparts into Typescript or should I opt to inject the existing jQuery into SPFX instead?

Transitioning from SharePoint 2013 to SharePoint online raises the question of how to migrate existing webparts that utilize jquery - ajax to SPFX client webparts. One possibility is rewriting all the code in Typescript, but is it possible to simply inje ...

Using TypeScript to extract types from properties with specific types

My current challenge involves working with a filter object derived from an OpenAPI spec. The structure of this object is illustrated below: export interface Filters { field1: string[] field2: string[] field3: boolean field4: number } My goal is to ...

Don't forget to include the line 'import "reflect-metadata"' at the beginning of your entry point for Jest tests

As I work on developing an application using dependency injection with tsyringe, I came across a case where a service receives the repository as a dependency. Here is an example: import { injectable, inject } from 'tsyringe' import IAuthorsRepos ...

The module 'AppModule' has imported an unexpected pipe. To resolve this issue, please include a @NgModule annotation

I have successfully created a custom pipe to remove duplicate items from an array and have imported it into my app.module.ts file Below is the code snippet: app.module.ts import { UniquePipe } from './_pipe/uniquePipe'; @NgModule({ imports: ...

When implementing useReducer with TypeScript, the error "Argument of type '(type, action) => { state: (...}' is not assignable to parameter of type 'ReducerWithoutAction<any>'" may occur

Recently, I decided to delve into learning TypeScript by building a simple shopping cart application. If you want to check out the code, feel free to visit my GitHub repository: https://github.com/CsarGomez/shopping-cart-reducers-tx I've encountered ...

Instructions for including a class are ineffective

I am trying to dynamically add a class to a div based on two conditions. To achieve this, I have created a custom directive as shown below: import { Directive, HostBinding, Input } from '@angular/core'; @Directive({ selector: '[confirmdia ...

Ways to verify and incorporate https:// in a URL for a MEAN Stack application

When extracting the URL from API data, my code looks like this: <div class="row copy-text"> <a href="{{copy.Url}}" target="_blank" style="text-decoration: underline !important;">{{copy.Title}}</a> </div> I am interested in ve ...

Warning from React 17: Unexpected presence of <a> tag inside <div> tag in server-rendered HTML

I've checked out the existing solutions and still can't seem to make it work. components/NavBar.tsx import { Box, Link } from "@chakra-ui/react"; import { FunctionComponent } from "react"; import NextLink from "next/link ...

Utilizing Angular's Dynamic Component Import and Loading capabilities

Looking to develop a portal that can dynamically load Angular components without the need for explicit imports. I've heard about using ComponentFactoryResolver for this purpose, but hoping to have the ability to store components in separate files or r ...