Getting started with Angular Observables, Quick tutorial

What is an RXJS Observable?

An Observable is a push system mechanism for JavaScript that allows you to do event programming. In that way, there are two parts of an observable. A producer pushes values in the system and the observers (or consumers) are processing these values. Then, in simple words we can say the producer is the emitter and the consumers are the receivers.

Basic usage

The first thing you need to understand about observables is that you need two parts of the mechanism to make it works. Indeed, you need an emitter and a receiver. In Observable, the emitter is the ‘next’ function and the receiver is the subscribe function. Let’s take an example with only emitter with no receiver:

currentValue: number;

ngOnInit(): void {
  this.numberAPI();
}

numberAPI(): Observable<number> {
   return new Observable<number>((subscriber: Subscriber<number>) => {
     this.currentValue = 0;
   });
}




<h1>
  {{ currentValue }}
</h1>



In this example, nothing appeared in the screen because the value is emitted but there is no receiver to handle the message. To solve this little problem, you need to subscribe to the function. And now it’s working:

currentValue: number;

ngOnInit(): void {
  this.numberAPI().subscribe(value => {
      this.currentValue = value;
    });
}

numberAPI(): Observable<number> {
  return new Observable<number>((subscriber: Subscriber<number>) => {
    subscriber.next(0);
    subscriber.complete();
  });
}

This is the minimum you need to know if you want to use observables. Let’s see in detail what is happening. First, we create the observable by simply returning an Observable object. The parameter of an observable object is the subscriber. The subscriber is the function you have to subscribed to let the magic happens. In the subscriber, we use the function next(object: any). This function represents the emitter and as you can see it can be any type of object (here it’s a number). Then comes the receiver with the function subscribe(…). This function opens the pipe between the emitter and the receiver to process data. So, in this case, 0 will be the value displayed

.

Ok, that’s great, but what is the complete function?

Good Question. Actually, the complete function is something REALLY important. It’s so important that it can cause many bugs if you forget it. You could spend hours to fix them if you don’t use it correctly. Remember, observables is a mechanism between emitter and receiver. You can also see them as a pipe. The complete function in the subscriber function allows you to close the pipe. It means ‘I DON’T WANT TO EMIT VALUES ANYMORE’. Let’s take a little example to illustrate my words:

currentValue: number;

ngOnInit(): void {
  this.numberAPI().subscribe(value => {
      this.currentValue = value;
    });
}

numberAPI(): Observable<number> {
  return new Observable<number>((subscriber: Subscriber<number>) => {
    subscriber.next(0);
    subscriber.complete();
    subscriber.next(1);
  });
}

The value displayed will be 0 because the complete function closed the pipe.

Ok, well, your complete function is just to close the pipe, but why can it cause many bugs?

Ah good question! In this simple case, it’s complicated to create an anomaly, but event programming is about dealing with hundreds of events at the same time. In angular, let’s imagine you have many components which are communicating between them, then one of them is still emitting when you destroy this component, depending on the purpose of this observable, it you can either cause a bug by emitting and processing values or use more memory that needed.

How do we deal with errors in observable?

Dealing with errors in observables is quite simple. You just have to call subscriber.error() in the emitter part and handle it in the receiver part. This will trigger a signal saying ‘STOP EVERYTHING, SOMETHING IS WRONG’. Let’s see the next example:

currentValue: number;

ngOnInit(): void {
this.numberAPI().subscribe(value => {
      this.currentValue = value;
    }, error => {
      console.error(error);
    });
}

numberAPI(): Observable<number> {
  return new Observable<number>((subscriber: Subscriber<number>) => {
    subscriber.next(1);
    subscriber.error('An error occurred');
  });
}

 

As you can see, we just add an arrow function in the subscribe method to handle the error. In this example, the value displayed will be 1 but we will have an error message in the console.

The relation between error() and complete() functions?

Actually there are quite similar. Both of them will close the pipe. The only difference is that one is an error and the other is a success (simple, right?). Let’s see the next example to understand my words:

  currentValue: number;

  ngOnInit(): void {
      this.numberAPI().subscribe(value => {
        this.currentValue = value;
      }, error => {
        console.error(error);
      }, () => {
        console.log('Completed');
      });
  }

  numberAPI(): Observable<number> {
    return new Observable<number>((subscriber: Subscriber<number>) => {
      subscriber.next(1);
      subscriber.error('An error occurred');
      subscriber.complete();
    });
  }

First, notice that the last arrow function in the subscribe function allows you to do a last thing before closing the pipe. If you do understand all my explanation, you should not be surprised by the result. Indeed, when an error occurred, everything stops. So the complete function is never triggered and we won’t see the message ‘completed’ in the console. So we can only deduce that the triggered error closed the pipe.

Conclusion

  • Observable allows you to deal with event programming.
  • No matter what you do, do not forget to close the pipe when you finished
  • Handling errors is quite simple
  • Errors and Complete are both closing the pipe

Be the first to comment

Leave a Reply

Your email address will not be published.


*