Triggering multiple updates within a single method in Angular will cause the effect or computed function to only be triggered

Upon entering the realm of signals, our team stumbled upon a peculiar issue. Picture a scenario where a component has an effect on a signal which is a public member. In the constructor of the component, certain logic is executed to update the signal value multiple times. The assumption was that the effect would be triggered the same number of times as the updates to the signal value were made. However, this does not happen as expected. Instead, the effect is only fired for the first time after the entire initialization process of the component.

To see an example of this behavior, you can check out the demo I have created on StackBlitz DEMO

  constructor() {
    effect(() => {
      this.effectLogs.push(JSON.stringify(this.valueSignal()));
      if (this.valueSignal().length == 1 || this.valueSignal().length == 2) {
        alert('Im never triggered');
      }
    });

    this.insertFirstValue();
    //  possibly some other logic here
    this.valueSignal.update((val) => [...val, 'constructor-1']);

    setTimeout(() =>
      this.valueSignal.update((val) => [...val, 'constructor-2'])
    );
  }

  ngOnInit() {
    this.valueSignal.update((val) => [...val, 'init-3']);
  }

  private insertFirstValue() {
    this.valueSignal.update((val) => [...val, 'constructor-0']);
  }

The result of the logs from setting up this effect look like this:

["constructor-0","constructor-1","init-3"]
["constructor-0","constructor-1","init-3","constructor-2"]

Since the initial effect already had 3 values pushed, the conditional alert in the effect never triggers. In our case, this complication extends further as our store feeding is based on conditions related to signal values, which exhibit the same unexpected behavior.

We began by isolating the problematic segment, hoping it was an error in our implementation. The demo demonstrates that it may be a general behavior. It could be a misunderstanding of how this should function at runtime, since we were unable to find documentation or solutions on platforms like Stack Overflow. In the example, I experimented by adding a button to input new entries twice, using computed properties, adding timeouts, but none seemed effective (except timeout).

Answer №1

When it comes to emitting update notifications, Signals have a unique characteristic compared to Observables.

The key difference is that Signals are designed to be glitch-free, with distinct update and notification phases.

This guarantees that when you read signals, you can be certain that they have all been updated.

As a result, not every signal update will immediately trigger an effect. The important concept to remember here is "eventually".

Signals eventually emit a notification indicating that they have been updated.

You can observe this behavior in action by checking the array size:

> 4
> 5

To demonstrate this, consider the following example:

const mySignal() = signal(1); 
effect(() => console.log(mySignal());

mySignal.set(2);
mySignal.set(3);
mySignal.set(4);

If you run this test, you'll notice that only 4 will be logged.

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

Comparing Angular 2's Seed and CLI: A closer look at

Exploring my options for beginning a fresh Angular 2 Project. I stumbled upon angular2-seed and angular-cli as potential tools for kickstarting the project. However, I am deliberating on which one to opt for and curious about their respective advantages a ...

Using a dictionary of objects as the type for useState() in TypeScript and React functional components

I am in the process of transitioning from using classes to function components. If I already have an interface called datasets defined and want to create a state variable for it datasets: {[fieldName: string]: Dataset}; Example: {"a": dataset ...

Error message: "ExpressionChangedAfterItHasBeenCheckedError in dynamic reactive forms"

This issue arises when utilizing nested reactive forms and the child component employs ng-if*. It's the template interpolation that leads to complications. You can refer to the reproduction here: https://plnkr.co/edit/GrvjN3sJ05RSNXiSY8lo //our root ...

Ways to grant access beyond the local host

I am having trouble accessing my Angular2 application outside of localhost. I can easily navigate to localhost:3030/panel, but when I try to use my IP address like 10.123.14.12:3030/panel/, it does not work. Can someone please help me fix this issue? I am ...

Efficiently finding a group of substrings within a JavaScript string

I am currently working on a method to efficiently search for specific substrings within a given string. Here is my current implementation: const apple = "apple" const banana = "banana" const chickoo = "chickoo" const dates = & ...

Guide on utilizing tslint in conjunction with npx

I currently have tslint and typescript set up locally on my project. In order to run tslint against the files, I am using the following command: npx tslint -c tsconfig.json 'src/**/*.ts?(x)' However, when I run this command, it seems to have no ...

Error message: Unable to modify headers after they have already been sent-NodeJS, MongoDB, and Mongoose

While working on a basic todo MEAN application with a remote database, I've encountered a strange issue. Whenever I try to update or delete a record (not always, but mostly), an error is thrown: events.js:160 throw er; // Unhandled 'error& ...

Nuxt 3 turns a blind eye to TypeScript errors upon code saving

I am facing an issue. Even with a TypeScript error in the code, the IDE shows an error, but I am still able to save it and run it in the browser. Is this acceptable? Check out the code below: <script lang="ts" setup> const a = ref<strin ...

The communication between Angular and Unity using SignalR for messaging is not functioning properly, as I am unable to

Trying to establish a connection between Angular and Unity has been challenging for me. I can't seem to get them to communicate with each other. My goal is to have Angular "announce" when someone enters a room, and have Unity "greet" the user enterin ...

Unable to locate a differ that supports the object '[object Object]' of type 'object'. NgFor is restricted to binding with Iterables like Arrays. Unfortunately, there is no current solution available for this issue

I'm encountering a minor issue with my code. I have two HTTP requests and after combining the data from both, I encounter an error when trying to loop through the final array. I've read other posts suggesting that the returned object is not an a ...

Is there a forEach loop supported in Angular2? If so, why does it display all objects with the same value?

Hello everyone, I'm currently facing an issue with getting server response objects and passing them into a new Array object. In the code snippet below, you can see that when I try to print these newly passed objects using a forEach loop, they appear a ...

Guide for retrieving a user object from an HTTP request

I am looking to retrieve only the user object from the request. public async getUserByHash(hash: IHash) { this.logger.log('Hash for check email accessed'); const user = await this.hashRepository.findOne({ select: ['id', ...

Enhancing the selection of options in Angular 2 using object values

When I retrieve a list of object values from an API, each object contains a property to identify the selected item. I am successfully binding the items list to the view. Here is the JSON data: https://i.sstatic.net/itmfh.png Below is my code snippet: & ...

Utilizing TypeORM to selectively choose data in OneToMany relationships

I am looking to create a TypeORM query that pulls data from the database. Specifically, I want to retrieve all clients who have made a purchase but have not initiated a return. Here is the structure of the database: Clients: Id (Int, primary column) Purc ...

Angular 2 does not allow access to the getSize() properties while using Protractor

I have been utilizing the Angular2 Go Protractor setup in an attempt to conduct end-to-end tests on Angular 2. While attempting to retrieve the size of an element, I have encountered issues with the properties not being accessible. For instance: var myEl ...

The null error occurs when rendering with React's state array

When I try to call an API that emits JSON, I am encountering an issue. I call the promise API function in componentDidMount, set the state, and then call it in the render method, but it always returns a null error. I need assistance, please. Interface fo ...

Angular 16 facing compatibility problems with Apollo-angular and React dependencies

I have integrated apollo-client into my Angular 16 project. "@apollo/client": "^3.8.7", "apollo-angular": "^5.0.2", "graphql": "^16.8.1", This snippet shows how the providers array is ...

Ionic app: refresher functionality works in browser but not on iOS home screen app

I am currently developing a Progressive Web App (PWA) using Ionic, and I have implemented an ion-refresher in the app: <ion-content> <ion-refresher slot="fixed" (ionRefresh)="refresh()"> <ion-refresher-content pullingIcon="lines">& ...

Strange Node.js: I always avoid utilizing `require()`, yet encountered an unexpected error

For more information on this particular issue, please refer to this link It's quite puzzling as I haven't used the require() function in my code, yet I'm receiving an error telling me not to use it. How odd! The problematic code snippet i ...

The jquery methods might encounter an issue with an undefined object

I have been attempting to implement a function that triggers when the user reaches the bottom of the window, but TypeScript is flagging errors and mentioning potential undefined objects related to window.scrollTop(), height(), and document.height(). Even ...