I’m working with Angular and trying to use signals within an effect()
. My goal is to trigger an action when a specific signal changes, but the action itself doesn’t need the signal’s value.
For example, I have an isAuthorized
signal, and I want to call fetchCars()
whenever the authorization status changes, but fetchCars()
doesn’t need to use the isAuthorized value.
constructor() {
effect(() => {
const isAuthorized = this.authService.userAuthorized();
// This function doesn't use the value of isAuthorized anyway.
this.fetchCars();
});
}
It works but it’s a bit odd to assign isAuthorized
to a constant without actually using it. Is there a more correct or elegant way to achieve this?
Angular Version: 18.0.1
1
You can use toObservable()
to convert the signal to an Observable:
constructor() {
toObservable(this.authService.userAuthorized)
.pipe(takeUntilDestroyed())
.subscribe(() => this.fetchCars())
}
toObservable
is part of the RxJS Interop package
which is currently in developer preview
and might undergo (breaking) changes before becoming stable.
2
I couldn’t find a better way other than to either use the toObservable()
as mentioned by @JSONDerulo or to trigger the signal getter inside the effect()
.
However you could define a named effect variable in the service that triggers the signal getter so that you don’t have to trigger it in every single component that uses the effect.
Try the following
Service
import { Injectable, signal, effect } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class AuthService {
public readonly userAuthorized = signal(false);
public readonly userAuthorizedEffect = (callback: () => void) =>
effect(() => {
this.userAuthorized();
callback();
});
public toggleAuthStatus(): void {
this.userAuthorized.set(!this.userAuthorized());
}
}
Component
export class App {
constructor(private readonly authService: AuthService) {
this.authService.userAuthorizedEffect(() => {
this.fetchCars();
});
}
fetchCars() {
console.log('fetching cars here...');
}
}
Working example: Stackblitz