Tutorial hero
Lesson icon

Signal Effect Branching with Conditionals in Angular

Originally published September 13, 2023 Time 2 mins

Generally, an effect in Angular will run once initially and then again whenever any of the signals it depends on change.

Let’s imagine you have an effect like this:

effect(() => {
  if(this.someElement){
    console.log(this.someSignal())
  }
})

The scenario here is that someElement is an element from the template accessed with ViewChild, and someSignal is just a regular signal.

The intent here might be to do something with someSignal every time it changes, but only if someElement exists. This seems like it might do the job, but it won’t.

What will actually happen is that the first time the effect runs, when someElement does not exist yet, it will ignore everything inside of this if conditional as it is not relevant. Now even when someSignal gets a new value later the effect will not run, because it is being ignored and someElement will never be re-evaluated.

One way to deal with this is to make sure that the conditional you are testing is also a signal, e.g:

effect(() => {
  if(this.someElement()){
    console.log(this.someSignal())
  }
})

If someElement is a signal, then the effect will be re-evaluated when its value changes, which would then allow the conditional to pass and for someSignal to no longer be ignored.

Generally, this is going to be the best solution - if you have things in your effects that change, make sure they are signals.

However, at least until future versions of Angular come out, it is somewhat awkward to get the result of @ViewChild into a signal so you might prefer to convert everything to signals. Another option is to create a local variable for the value of someSignal:

effect(() => {
  const value = this.someSignal();

  if(this.someElement){
    console.log(value)
  }
})

Now that someSignal is referenced outside of the conditional it will trigger this effect whenever it is changed, and then someElement will also be re-evaluated as a result of this.

Learn to build modern Angular apps with my course