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

"Manipulating values in an array with a union type: a guide to setting and

I am currently working on creating an array that can have two different value types: type Loading = { loading: true } type Loaded = { loading: false, date: string, value: number, } type Items = Loading | Loaded const items: Items[] = ...

What is the best way to extract a property if it may be undefined?

Can anyone help with this TypeScript error I'm encountering during build time? Any suggestions would be appreciated. Error Message: TypeError: Cannot destructure property 'site' of '(intermediate value)' as it is undefined. export ...

Specify the second parameter as a generic class that corresponds to the first parameter of the function

Given the example below, the second parameter of the fn function requires a class with a static attribute controle and an instance attribute controle, both of type number. interface Base { controle: number new(...args: any[]): { controle: n ...

Exploring the creation of an Angular service that utilizes HttpClient for making GET requests, with a focus on the different

I've been diving into Angular lately and I'm facing some challenges with handling get requests. If you're interested, you can check out my code on Angular Stackblitz import { HttpClient} from '@angular/common/http'; import { Inject ...

Tips on hiding the menu toggler in PrimeNg

Struggling with PrimeNg implementation in my Angular project, I am unable to find a simple solution to hide the menu toggler. Allow me to illustrate my current setup in the first image and what I desire in the second. Let's dive in: View First Image ...

Arrange the angular datatables in a specific order without displaying the usual user interaction triangles

I am looking to arrange the data in a fixed manner without any user interaction for sorting. However, it seems that I can either completely disable ordering like this: this.dtOptions = { paging: false, lengthChange: false, searching: false, orderi ...

Steps for clicking on the center of a leaflet map with protractor

I'm currently facing an issue where I am attempting to click on the center of a map located in the second column of the webpage, which has an offset. However, I am encountering a problem where the cursor always points to the center of the page instead ...

How can I utilize the Redux store outside of a component in a React application with ASP.NET Core and TypeScript?

While I have some experience with React, I am new to using Redux. Luckily, Visual Studio 2017 comes with a built-in template for React + Redux under .NET Core 2.0. About my environment: Visual Studio 2017 React 15.6.1 TypeScript 2.4.1 Redux 3.7.1 Rea ...

Instructions on utilizing type interfaces for prop drilling in my React Typescript counter

I am currently developing a basic counter app to monitor my progress in a digital card game that I enjoy playing. While attempting to pass props from the parent component to the child component, I encountered an issue where the props were not being success ...

Retrieve Json data from an external API in Angular by utilizing the HttpClient module

Being a novice in angular, I am experimenting with fetching data from an external API. Although I managed to retrieve the data successfully on the console, I encountered errors when attempting to display it on the screen. Below are the details of my setup: ...

Tips for indicating ngbDatepicker as valid in a form even without selecting a value

In my Angular2 project, I am utilizing ng-bootstrap's ngbDatepicker within a Reactive Form. The dates in this form are not required, but the problem is that ngbDatepicker always considers the form as Invalid unless a date is chosen. Is there a method ...

Top method for continuously updating the position of DOM elements in Angular 2

Currently, I am in the process of developing a game using Angular (version 4). I understand that direct manipulation of the DOM is typically not recommended when working with Angular. However, for the particular functionality I'm trying to achieve, I& ...

How can you position the input cursor at the end of the default text when navigating through fields with the tab key?

I've implemented tab index in the HTML to navigate from one field to another. In the image below, you can see me tabbing from "Revise" to "Link". https://i.stack.imgur.com/vb6L.png However, when I press tab, the default text in the Link field is fu ...

When interacting with the iframe in an Ionic3 app, it suddenly crashes

Greetings! I have integrated a flipping book URL inside an iframe: <ng-container> <iframe [src]="eUrl" id="flipping_book_iframe" frameborder="0" allowfullscreen="allowfullsc ...

Building a theme with TypeScript in React

As I embark on my React project, I've been tasked with creating a CSS using TypeScript while referring to the color palette diagram provided below. Utilizing createMuiTheme to build the theme, I've realized that there are various possible conditi ...

step-by-step guide to leveraging the heatmap functionality of google maps with angular agm

For my current Angular 5 project, I am utilizing the angular component @agm/core found at https://github.com/SebastianM/angular-google-maps to display Google Maps. It's been working well so far, but now I'm looking to incorporate a heatmap layer ...

A guide on launching a Vite React application from a subdirectory

Utilizing Vite to develop a React application. Routes.tsx import { RouteObject, createBrowserRouter } from "react-router-dom"; import App from "../layout/App"; import HomePage from "../../feautures/home/HomePage"; import Crea ...

The specified file is not located within the 'rootDir' directory in the Cypress tsconfig.json file

I've encountered an issue while configuring Cypress in my Project, specifically with the typescript setup for Cypress. Here is the structure of my project: fronend/ - cypress/ -tsconfig.json - src/ - tsconfig.json - package.jso ...

Incorporate a CSS framework into the Angular vendor bundle

My current situation : The website is built with Angular 4 Started using Angular Starter Kit Utilizing Semantic UI as the CSS framework The challenge I'm facing : Integration of Semantic UI into webpack is not having any impact. Steps I've ...

Adjust the input width dynamically in Angular

Looking to dynamically adjust the width of an input field and ensure that the suffix "meters (m)" sticks close to the entered number. Additionally, I want to pass a specific value to the input using `value="something"`, which then should expand the input w ...