What is the method for updating a 'Signal' within an 'Effect'?

Working with signals in Angular 17, I encountered an issue while trying to update the value of a signal. The error message that I received is as follows:

NG0600: Writing to signals is not allowed in a `computed` or an `effect` by default. Use `allowSignalWrites` in the `CreateEffectOptions` to enable this inside effects.

Despite my efforts to find a solution, I have not come across any useful information.

Essentially, my goal is to update the signal value based on a specific condition within the Effect method:

Component:

export class LibGridViewComponent {
    private _libSubjectsGiproService = inject(LibSubjectsGiproService)

    constructor() {
    effect(() => {
      this.getValuesBySearchSignal()
    });
  }
  
  getValuesBySearchSignal(displaySource?: any): any[] {
    let testArr = [
      {
        "name": "B179 HEPATITIS VIRAL AGUDA NO ESPECIFICADA",
        "value": "B179"
      },
      {
        "name": "B980 HELICOBACTER PYLORI [H.PYLORI] COMO LA CAUSA DE ENFERMEDADES CLASIFICADAS EN OTROS CAPITULOS",
        "value": "B980"
      },
      {
        "name": "C799 TUMOR MALIGNO SECUNDARIO - SITIO NO ESPECIFICADO",
        "value": "C799"
      },
    ]

    let searchTerm = this._libSubjectsGiproService.getSearchTerm()
    
    let foundSource:any = []

    if (searchTerm && searchTerm != '') {
      foundSource = testArr.filter(i => i.name.toLowerCase().includes(searchTerm));

        let currentSource = this.initialDisplaySource.value;
        this.initialDisplaySource.next([...currentSource, ...foundSource]);
        this._libSubjectsGiproService.setSearchTerm('')
    } else {
      this.initialDisplaySource.next([])
    }

    return this.initialDisplaySource.value
  }
}

Service:

export class LibSubjectsGiproService {
    searchTerm: WritableSignal<any> = signal<any>('');
    
    setSearchTerm(value: any) {
    this.searchTerm.set(value);
  }

  getSearchTerm() {
    return this.searchTerm();
  }
}

UPDATE: To provide more context on my objective, I have a grid view with a Select column that allows users to search for items. While it's possible to add new rows to the table, the search term remains the same. My aim is for the signal to be empty each time a new row is added, ensuring that initialDisplaySource is also empty until the user begins typing.

Answer №1

Caution: feature is presently in the testing phase for developers

Snippet of code illustrating how to activate the "allowSignalsWrite" flag:

  constructor() {
    effect(() => {
      this.getValuesBySearchSignal()
    }, { allowSignalWrites: true } );
  }

This is not advised and is not turned on by default because using a signal might create a loop that can cause the browser to hang.

This may lead to a critical problem that is difficult to identify as the application expands.

Answer №2

While it is possible to accomplish this using the effect method, it may not be the most optimal solution. This is because updating the signal will trigger the effect, requiring additional steps to reset the signal, which is not recommended in the documentation. Instead, it is advised to utilize HTML events that only occur when the user changes the input.

If you are set on using the effect method, consider the alternative suggestion provided in my response.

Essentially, we can invoke the getValuesBySearchSignal function when the user types in the select. Without access to the HTML, we can utilize events like (ngModelChange), (change), (input) to trigger the function and manage the signal reset and other necessary tasks.

<input [(ngModel)]="" (ngModelChange)="getValuesBySearchSignal()"/>

In this scenario, we can simply set allowSignalWrites to true in the effect options.

  constructor() {
    effect(() => {
      this.getValuesBySearchSignal()
    }, {
        allowSignalWrites: true
    });
  }

It is important to consider the drawbacks of using allowSignalWrites, which are outlined in 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

Combining data from various API calls into one cohesive array using RXJS

My RXJS Pipeline is structured as follows: const logs: number[] = [1, 2, 3, 4]; const url = 'http://some-url-here.com'; const pipeline = from(logs).pipe( switchMap(logId => this.callEndpoint(url, logId).pipe(map(response => response. ...

Avoid the occurrence of the parent's event on the child node

Attempting to make changes to an existing table created in react, the table is comprised of rows and cells structured as follows: <Table> <Row onClick={rowClickHandler}> <Cell onCLick={cellClickHandler} /> <Cell /> ...

Expanding Arrays in TypeScript for a particular type

There is a method to extend arrays for any type: declare global { interface Array<T> { remove(elem: T): Array<T>; } } if (!Array.prototype.remove) { Array.prototype.remove = function<T>(this: T[], elem: T): T[] { return thi ...

What is the proper way to implement an if-else statement within objects?

Is there a way to convert the code below into an object structure so I can access nodID and xID keys from different files? The issue lies in the if statement within the code. My idea is to use export const testConfig = {} and import testConfig into any fil ...

I'm seeking clarity on the proper replacement for ngModel within this Angular code, as I've been cautioned about using form control name and ngModel simultaneously

I have been using ngModel and formControlName together, which is causing a warning to appear in the console. I am trying to resolve this issue by removing ngModel, but I'm unsure of what to replace it with. I've attempted a few solutions, but non ...

Is it possible to confirm that a value is a valid key without prior knowledge of the object's keys during compile-time?

Is there a way in TypeScript to declare that a variable is a keyof some Record without prior knowledge of the keys? For instance, consider an API response returning JSON data. Is it possible to define a type for the keys of this payload to ensure that whe ...

Utilize @agm/core in Angular 6 to load Google Maps by first retrieving latitude and longitude data from the server

I am currently developing a project in Angular6 that involves utilizing the "AGM - Angular Google Maps" library for mapping functionalities. One of the requirements is to dynamically draw the map based on latitude and longitude data fetched from the serve ...

JSX is restricted in files using the '.tsx' extension according to eslint rules (react/jsx-filename-extension)

When working in a .tsx file, why does eslint flag the following issue: The use of JSX is not permitted in files with the extension '.tsx' (eslint react/jsx-filename-extension) What steps can I take to adjust the eslint configuration and addres ...

Trouble with Angular toggle switch in replicated form groups

Currently, I have a form group that contains multiple form controls, including a toggle switch. This switch is responsible for toggling a boolean value in the model between true and false. Depending on this value, an *ngIf statement determines whether cert ...

Having trouble locating a file in WebStorm? Try accessing WebStorm through the terminal instead

Starting WebStorm from the terminal Version: WebStorm 2016.3.3 I suspect that the reason it's not functioning is due to emojis in some of my file names. Do you think this could be the issue, or is there another root cause for the problem? Can emoji ...

Testing Angular 2's IF condition with unit tests

I just started learning about unit testing and I am currently working on testing the if condition in the code snippet below: hide() { this.count --; if (this.count === 0) { this.loaderIs = false; } } My goal is to ...

Could the repeated utilization of BehaviorSubject within Angular services indicate a cause for concern?

While developing an Angular application, I've noticed a recurring pattern in my code structure: @Injectable(...) export class WidgetRegsitryService { private readonly _widgets: BehaviorSubject<Widget[]> = new BehaviorSubject([]); public get ...

Changing HTML tags programmatically in Angular while inheriting a template

In my project, I have a Component called DataGrid that represents a table with expandable rows. Each row can be expanded to show a child DataGrid table, which is similar to the parent DataGrid component. To simplify this setup, I created a base class DataG ...

Using nodemailer to send an email with a dynamic variable that holds the HTML content

I am attempting to send a variable containing HTML code from a Vue component using the POST method. My technology stack includes TypeScript, Nuxt.js, Node.js, and Vue.js. const order_list = document.querySelector('table') as HTMLInputElement | n ...

Organize and display a list of contacts alphabetically by the first letter of their

I have a list of contacts that I need help with. Despite searching on Stack Overflow, I couldn't find the answer. Can someone please assist? Thank you. export const rows = [ { id: 1, name: 'Snow', email: 'Jon', co ...

Issue with Service Workers functionality in Angular 8 has been identified

Issue http://localhost:8080/ Requests that are not handled will be directed to: http://localhost:8080 Press CTRL-C to stop the server [2019-06-21T06:37:57.110Z] "GET /" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Geck ...

The issue of sending a POST request with form-data body parameters is not functioning as expected in Angular 2

I have successfully sent a file and other parameters in the body with type 'form-data' using Postman. Now, I am trying to achieve the same functionality in Angular 2. Please refer to the screenshot of the request made in Postman: https://i.stack. ...

Switch things up in the mat-tree angular

Is there a way to change the orientation of a mat-tree-node to "RTL" and adjust the padding to be on the right side? <mat-tree [dataSource]="dataSource" [treeControl]="treeControl"> <mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggl ...

The response error from the callback of the HTTP service in CouchDB with AngularJS lacks any meaningful data

I need help writing CouchDB TypeScript classes with AngularJS http service. My call is successful in the happy path, but I'm struggling to retrieve the status code or JSON error information from the server, which is crucial for user feedback. public ...

Tips for activating scroll feature for certain section of an HTML page

For the styling of my page, I'm utilizing Scss and am facing an issue related to setting up scrolling for specific sections of an HTML page. You can check out the image reference here. During a scroll event, I want to ensure that the Categories (left ...