"Debating Angular: Comparing the Use of Getters and Methods in

To prevent cluttering the *ngIf directive with logic directly in the template.

<div *ngIf="a === 3 && b === 'foo'"></div>

I typically create a custom method like this:

public isOk(): boolean {
  return a === 3 && b === 'foo'
}

and then update the code to use the method:

<div *ngIf="isOk()"></div>

Is this considered good practice?

Should we use a method or would it be better to use a getter instead?

What are the advantages and disadvantages of each approach?

If using a getter, the code would look like this:

public get isOk(): boolean {
  return a === 3 && b === 'foo'
}

And the template code would be updated accordingly:

<div *ngIf="isOk"></div>

Answer №1

A more effective approach involves adding a new property to your component class.

Component class:

...
// If both a & b change, for example if you are subscribed 
// to an Observable in ngOnInit
isOk: boolean; 

ngOnInit(): void {
  this.httpService.getSomeData()
    .subscribe(data => this.isOk = data.a === 3 && data.b === 'foo');
  // Remember to unsubscribe
}
...

In the component template:

<div *ngIf="isOk"></div>

Otherwise, your getter or method will be called every time angular triggers change detection.

Answer №2

To achieve peak performance, it is recommended to utilize rxjs in conjunction with the | async pipe.

For instance, consider the sample application below:

@Component({
  ...,
  template: `
    <h1 *ngIf="isOk()">Hello world!</h1>
    <input type="number" [(ngModel)]="a">
    <input type="text" [(ngModel)]="b">`,
})
export class App implements DoCheck {
  a = 0;
  b = '';

  isOk() {
    console.log('ran function');
    return (this.a === 3) && (this.b === 'foo');
  }

  ngDoCheck() {
    console.log('DoCheck');
  }
}

This leads to the following outcome:

https://i.sstatic.net/RlEkh.png

It's important to note that the function is executed multiple times upon each change, including when simply interacting with one of the textboxes.

If Observables are utilized instead, results will be as shown in this example:

@Component({
  ...,
  template: `
    <h1 *ngIf="isOk$ | async">Hello world!</h1>
    <input type="number" [ngModel]="a$ | async" (ngModelChange)="a$.next($event)">
    <input type="text" [ngModel]="b$ | async" (ngModelChange)="b$.next($event)">
  `,
})
export class App implements DoCheck {
  a$ = new BehaviorSubject<number>(0);
  b$ = new BehaviorSubject<string>('');
  isOk$: Observable<boolean>;

  constructor() {
    this.isOk$ = combineLatest([this.a$, this.b$])
      .pipe(map(([a, b]) => {
        console.log('ran function');
        return (a === 3) && (b === 'foo');
      }));
  }

  ngDoCheck() {
    console.log('DoCheck');
  }
}

The outcome of this approach can be viewed here:

https://i.sstatic.net/UUL6x.png

It should be observed that the rxjs map function is only triggered upon changes in inputs, minimizing unnecessary executions.

Moreover, the ChangeDetection strategy can now be adjusted to OnPush:

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

Outside the observable in Angular, there is a vacant array

Within my Angular application, I am facing an issue with the following code snippet located inside a method: let cardArray: string[] = []; this.cardService.getCards().subscribe((cards) => { console.log("1", cards); for (const card of car ...

Crack encrypted information using Typescript after it was encoded in Python

I've encountered an issue while attempting to decrypt previously encrypted data in Python. Here is how I encrypt the data in Python: iv = Random.new().read( AES.block_size ) cipher = AES.new(secret_key, AES.MODE_CBC, iv) encrypdata = base64.b64enco ...

Creating a dynamic component in Angular using the ng-template approach

Exploring Components using ng-template @Component({ template: ` <div>Welcome to the Component!</div> <ng-template #contentTemplate> <div>This is the template content</div> </ng-template> `, }) expo ...

Using Jasmine to Jest: Mocking Nested function calls

I am currently working on testing my TypeScript functions with Jasmine: //AB.ts export async function A() { } export async function B() { A(); } My goal is to unit test function B by mocking out function A to see if it is called. Here is the code I h ...

What is the best way to make an attribute in an interface mandatory only when another attribute is set to true

How can a relative be made required only when another attribute is true? For Example: interface ITesteProps { required: boolean content{!required && '?'}: string } I understand that this code is not valid. Is it possible to make the ...

Transform every DIV element into a TABLE, replacing each DIV tag with a combination of TR and TD tags

I have a code that is currently structured using DIV elements. However, I've encountered alignment issues when rendering it in EMAIL clients. To address this problem, I am looking to convert the DIV structure to TABLE format. Below is the original co ...

Create a Typescript type extension specifically designed for objects with nested arrays of objects

After stumbling upon this inquiry, I am eager to adjust my code in a similar fashion, utilizing typescript and a more intricate object. Consider the type below: export type ImportationType = { commercialImportation: boolean dateToManufacturer: string ...

How can one utilize JSON.parse directly within an HTML file in a Typescript/Angular environment, or alternatively, how to access JSON fields

Unable to find the answer I was looking for, I have decided to pose this question. In order to prevent duplicates in a map, I had to stringify the map key. However, I now need to extract and style the key's fields in an HTML file. Is there a solution ...

Unable to retrieve selected value from Flowbite-React Datepicker due to malfunctioning props change event

I am encountering an issue with extracting the selected value from the Datepicker component in the flowbite-react library while using it with NextJS. The component is being displayed correctly. I attempted the code below, but it does not return anyth ...

Discover the effective method in Angular to display a solitary password validation message while dealing with numerous ones

Here is the pattern we use to validate input fields: The length of the input field should be between 6 and 15 characters. It should contain at least one lowercase letter (a-z). It should contain at least one uppercase letter (A-Z). It should contain at le ...

Navigating with Angular's routerLink to specific paths allows for

My goal is to access localhost:4200/route/SOME_PARAMETER, with SOME_PARAMETER representing a component property. My current code snippet looks like this: <a [routerLink]="['/route/${SOME_PARAMETER}']"> However, it seems to be ...

The formatting for Angular material radio buttons is malfunctioning

My attempt to include a mat-radio-button in my code is encountering issues. The styles are not applying correctly, despite not having any custom classes or style overrides for the radio buttons. The fill element is off-center and lacks the Angular Material ...

Verify an entry with exactly 7 numerical digits

When inputting data, the user is limited to entering only 7 figures. If more than 7 figures are entered, an error message will display: "You need 7 digits". For instance, if the user enters something like this: 12345678910 The error message is correctly ...

Looking to adjust the API response to fit the necessary JSON format for an Angular project?

A modification is needed in the API response to align with the required JSON format provided below. The current responses and the desired format are detailed for reference. Assistance is appreciated. The current representation of individual's data ne ...

Unable to retrieve data from localStorage in Next.js

Unable to access localStorage in Nextjs. Code works as expected without errors, but the terminal throws: ReferenceError: localStorage is not defined at MainGrid (./app/components/WeightDisplay/MainGrid.tsx:17:96) 8 | // Initialize states for prefe ...

Steps to activate a function within an angular6 form-related directive

Is there a way to execute a function within a directive when the form is marked as pristine? I want to apply a CSS class to a tab header when the form is pristine. <form [formGroup]="awayForm" (ngSubmit)="onSubmit()" awayConfirm [cancelClicked]="cancel ...

Glitch causing incorrect images to appear while scrolling through FlashList

Currently, I am using the FlashList to showcase a list of items (avatars and titles). However, as I scroll through the list, incorrect images for the items are being displayed in a mixed-up manner. Based on the explanation provided in the documentation, t ...

Development in Angular 2 with a team of developers utilizing TFVC for version control and managing node_modules

With over 20,000 files in the node_modules directory, it may not be practical to include them in source control. This results in developers having to run 'npm install' every time they perform a 'get latest' in order to download any mis ...

Unexpected behavior of ion-select: No rendering of selected value when applied to filtered data

I came across an unexpected issue with the dynamic data filtering feature of ion-select. In my application, users are required to choose three unique security questions during registration. I have an array of available questions: questions: Array<{isSe ...

Nativescript encountered an error due to an undefined variable called FIRAuth

I'm currently working on a project using Nativescript. While everything runs smoothly with Firebase on the local emulator, I encounter errors when testing the application on my iPhone. The specific error message is: CONSOLE LOG file:///app/vendor.js ...