angularangular-signals

use effect and afterNextRender together


I have a signal effect that I want to run only in the browser (and nothing in the server)

but both effect and afterNextRender require being run from the injection context

so running this code

effect(() => {
  afterNextRender(() => {
    // ...
  });
});

throw ERROR Error: NG0203: afterNextRender() can only be used within an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`. Find more at https://angular.io/errors/NG0203

and running

afterNextRender(() => {
  effect(() => {
    // ...
  });
});

throw ERROR Error: NG0203: effect() can only be used within an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`. Find more at https://angular.io/errors/NG0203


Solution

  • afterNextRender() will run once, after the first rendering. effect() will run every time the signals it reads are changed.

    So the idea to run effect() inside afterNextRender() looks suspicious - you either want to run some code when signals are updated, or afterNextRender().

    But there is a solution to let you run it as you want:

    class Example {
      private readonly injector = inject(Injector);
      
      constructor() {
        afterNextRender(() => {
          effect(() => {
              // ...
            }, 
            {injector: this.injector}
          );
        });
      }
    }