0

Suppose I have something like this:

 submit(): void {
    this.loading = true;
    dataLength?: number = untracked(this.dataService.data)?.length;
    this.dataService.addData(this.dataForm.value);
    effect(
      () => {
        if (this.dataLength !== this.dataService.data().length) {
          this.loading = false;
          //Show success message
        }
      },
      { injector: this.injector }
    );
  }

This is pretty much self explanatory - once the user clicks on a submit button, a progress spinner is popped up. When the data changes as a result of the addData() call - the progress spinner disappears. Cool, it works.

However, it raises two main question,

  1. What happens if addData() throws an error?
  2. What happens if I have another source that updates dataService.data, for example, a polling mechanism?

In the context of RxJS we have catchError for dilemma #1 (that would also do this.loading = false but would show an error message instead). For the second part, we can use skipWhile on the other observer to disable the polling while this.loading is true.

What are the correct ways to handle those kind of issues?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
noamyg
  • 2,747
  • 1
  • 23
  • 44

1 Answers1

1

The correct way is to not be afraid to mix observables with signals.

Some things are handled better with signals (UI state), and some - with observables (user input events, component outputs modifications, router events, network requests).

Observables have a "complete" state (which is important for network requests) and they don't need an initial value (and signals can not exist without it).

Network requests emit the value later, that's why for the network requests it's better to use observables.


More about it you can read in free articles:
Angular Signals & Observables: Differences
Exploring Angular Signals

OZ_
  • 12,492
  • 7
  • 50
  • 68
  • In reality, most of the application UI state is based on network requests output. If I do something like `apiService.getData()` which returns `Observable`, then probably converting it `toSignal` would be an anti-pattern. That would also force me to `subscribe`. I also feel the same way about the other way around - i.e. when I have data that originates from the UI, converting it to an obs$ just so I can use `filter` or `distinctUntilChanged` before dispatching it. That leaves a very small room for Signals to fit into. – noamyg Aug 22 '23 at 19:56
  • Requests are just one of the possible ways to modify the state. Code that modifies the state is called a "side-effect". Signals are not suitable for every kind of reactivity, but they are perfect for the app state representation. You can find an example of implementation here: [Application State Management with Angular Signals](https://medium.com/@eugeniyoz/application-state-management-with-angular-signals-b9c8b3a3afd7) – OZ_ Aug 23 '23 at 08:37