Does this fall under the category of accepted practices for employing an effect in Angular?

I am working on integrating an Angular directive with a signal that receives values from a store selector. This signal is crucial for determining whether a button should be disabled or not. I'm curious about the best approach to listen to this signal - can I utilize the effect (or is it considered bad practice?) or is there a better alternative?

Within my directive, the effect resides in the constructor, and I previously attempted using ngOnChanges (an outdated piece of code that I modified as I shifted to using signals). The MaintenanceDisableErp signal originates from a selector.

I learned from the documentation that signals are designed for "Adding custom DOM behavior that can't be expressed with template syntax". Is this the intended purpose of signals in this scenario?

import {
  Directive,
  Input,
  HostListener,
  Renderer2,
  ElementRef,
  inject,
  effect,
} from "@angular/core";
import { MatSnackBar } from "@angular/material/snack-bar";
import { NotificationService } from "@core/services/notification.service";
import { Store } from "@ngrx/store";
import { toSignal } from "@angular/core/rxjs-interop";
import { selectDisabledErp } from "@core/_state/core.reducer";

@Directive({
  selector: "[appErpDisabled]",
})
export class DisableNotifyDirective {
  store = inject(Store);
  maintenanceDisableErp = toSignal(this.store.select(selectDisabledErp));

  constructor(private el: ElementRef, private renderer: Renderer2) {
    effect(() => {
      this.renderer.setAttribute(
        this.el.nativeElement,
        "disabled",
        this.maintenanceDisableErp() ? "true" : "false"
      );
    });
  }

  
}

Answer №1

If it were up to me, I would recommend utilizing a host binding in your situation to avoid having to manipulate the renderer (It's best to steer clear of the renderer when possible):

export class DisableNotifyDirective {
  store = inject(Store);

  @HostBinding('disabled') shouldDisable = false

  constructor() {
    this.store.select(selectDisabledErp).pipe(takeUntilDestroyed()).subscribe(disabled) {
      this.shouldDisable = disabled
    }
  }
}

Update: In response to your initial query, effect() is specifically designed for signals. It triggers when the signal is updated. Refer to the documentation

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

Unable to locate module '@angular/core' while utilizing PrimeNG

After installing PrimeNg, I attempted to use the sidebar component in my project. However, upon running the project, an error occurred: ERROR in /home/haddad/projects/node_modules/primeng/components/sidebar/sidebar.d.ts (1,97): Cannot find module '@a ...

Guide on how to upload files to a web server using Angular frontend only

My website's frontend is built with Angular and it allows users to upload files. I am looking for a way to store these uploaded files on the web server where my website is currently hosted. Ideally, I would like to accomplish this using just Angular, ...

When the mat-tree collides with a stylish css grid

Is there a way to transform a lengthy checkbox tree into a more manageable grid layout? The main issue is the lack of grouping wrappers, with only partial padding indicating group relationships. Check out this StackBlitz link for reference It seems that ...

extract objects from an array of objects based on a specified array

Within my JSON array, I have data structured like this: const data = [ { "uniqueId": 1233, "serviceTags": [ { "Id": 11602, "tagId": "FRRRR", "missingRequired&quo ...

Error in Typescript index: iterating over properties of a typed object

My scenario involves an interface that extends multiple other interfaces from an external library: interface LabeledProps extends TextProps, ComponentProps { id: string; count: number; ... } In a different section of the codebase, there is an ...

Dynamic user input using an enumeration

I am looking to develop a flexible input component (in React) that can dynamically generate different types of inputs based on the enum type provided along with relevant inputProps. The idea is to switch between different input components based on the type ...

When the property "a" is set to true, it must also require the properties "b" and "c" to be included

I'm looking for a way to modify the following type structure: type Foo = { a: boolean; b: string; c: string; } I want to change it so that if a is true, then both b and c fields are required. However, if a is false or undefined, then neither b ...

Is Angular4 preloaded with bootstrap library?

I started a new angular4 project and wrote the code in app.component.html <div class="container"> <div class="row"> <div class="col-md-1">.col-md-1</div> <div class="col-md-1">.col-md-1</div> <div class ...

Issues with multiple validators in Angular 8 intricately intertwined

I'm facing an issue with a reactive form control that has multiple validators. Despite defining the validation methods, the form is not being validated as expected. Below is the code snippet illustrating my attempted solutions. Method 1: civilIdNumbe ...

React-Redux: Unable to access the 'closed' property as it is undefined

Encountered a problem when using dispatch() in React-Redux. Specifically, the action below: export const fetchMetrics = () => { dispatch(fetchMetricsBegin); APIService.get('/dashboard/info/') .then((response) => { ...

What is the process of integrating Formik with Chakra using typescript?

I'm attempting to implement the following Chakra example in Typescript. <Formik initialValues={{ name: "Sasuke" }} onSubmit={(values, actions) => { setTimeout(() => { alert(JSON.stringify(values, null, 2)); actio ...

Event-Propagation in Angular 5 with mat-expansion-panel within another component

In my project, I am facing a challenge where I need to create multiple mat-expansion-panels within one mat-expansion-panel. Everything works fine except for the issue that when I try to open a child-panel, it triggers the close-event of the parent-panel. ...

Discovering the type in Typescript by specifying a function parameter to an Interface

Consider this sample interface: interface MyInterface { x: AnotherThing; y: AnotherThingElse; } Suppose we make the following call: const obj: MyInterface = { x: {...}, y: {...}, } const fetchValue = (property: keyof MyInterface) => { ...

In Javascript, check if an item exists by comparing it to null

I am working with a dropdown list that can be used for various types of data. Some of the data includes an isActive flag (a BOOLEAN) while others do not. When the flag is absent, I would like to display the dropdown item in black. However, if the flag exis ...

When converting an NgbDate to a moment for formatting needs, there is a problem with the first month being assigned as 0 instead of 1

I am encountering a challenge with my Ngb-Datepicker that allows for a range selection. To customize the output format, I am using moment.js to convert the NgbDate into a moment object (e.g., Wed Jan 23). One issue I encountered was that NgbDates assign J ...

Showing the AngularFireList data on the HTML page following successful retrieval

Does anyone know how to display an AngularFireList on an HTML page? import { Component } from '@angular/core'; import { NavController } from 'ionic-angular'; import {AngularFireAuth} from 'angularfire2/auth'; import {AngularF ...

Updates made to Angular components do not get transpiled to JavaScript

Embarking on my first ASP.NET Core application journey with Angular 2! User access is a top priority for the application. Facing the absence of an Angular template in Visual Studio 2017, I opted to use Powershell and Yoman to generate an Angular project s ...

Angular HTTP client fails to communicate with Spring controller

Encountered a peculiar issue in my Angular application where the HttpClient fails to communicate effectively with the Spring Controller. Despite configuring proper endpoints and methods in the Spring Controller, the Angular service using HttpClient doesn&a ...

Consistently scaling the Embla carousel slides for a seamless presentation experience

In my current project, I am utilizing Embla Carousels and aiming to incorporate a smooth slide scaling effect as users scroll through. The idea is for slides to enlarge the closer they get to the left edge of the carousel container, then decrease in size r ...

What is the reason behind Angular FormControl applying the 'disabled' attribute in the DOM but not the 'required' attribute?

After transitioning my form logic from the template to FormGroup & FormControl objects, I noticed that when a FormControl is disabled in Angular, the 'disabled' attribute for the field is automatically updated in the DOM. However, when I modi ...