Check out our Angular Book Series.

What is the new syntax for subscribing to Observables?

I was working on an Angular project, and noticed a warning when subscribing to an Observable. I had something like:


myObservableHere.subscribe((result: any) =>
{
console.log(result);
}, (err: any) => {
console.log(err);
});

I subscribe to the Observable, then put a comma separated list of methods. The first one is the next() method, and next comes the error() method, and finally we get a complete() method--left out of the sample above.

I've been using this syntax for what feels like forever, but today I was noticing a deprecated warning:

Use an observer instead of an error callback

I am using an Observable, why is this causing issues? First, it says to use an Observer, not an Observable. There is a distinction between them. The Observer is the value inside the Observable that is used to trigger the next, completed, or error messages. For most of my development this detail is hidden from me.

Instead of listing out each individual functions, we now can pass in an object and name them.

The new syntax would be like this:


myObservableHere.subscribe({
next: (result: any) =>
{
console.log(result);
},
error: (err: any) => {
console.log(err);
},
complete: () => {
console.log('complete');
}
});

The Observer that we pass in, is an object, and it contains three properties: next, error, and complete. Each one represents a function that will be triggered automatically from the observable.

If you drill into the code, you find some interesting things. In IntelliJ I just control-clicked on the subscribe() method to open up Observable.ts:


subscribe(observer?: PartialObserver<T>): Subscription;
/** @deprecated Use an observer instead of a complete callback */
subscribe(next: null | undefined, error: null | undefined, complete: () =>
void): Subscription;
/** @deprecated Use an observer instead of an error callback */
subscribe(next: null | undefined, error: (error: any) => void, complete?: () => void): Subscription;
/** @deprecated Use an observer instead of a complete callback */
subscribe(next: (value: T) => void, error: null | undefined, complete: () => void): Subscription;
subscribe(next?: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription;

First, while three options are deprecated, the fourth one is not and our first syntax is okay. We only run into problems if the next, error, or complete function are null or undefined.

But, look at the first item int he list. The argument it expects is a PartialObserver; not an Observer. I control-clicked again to go to a types.ts file:


export type PartialObserver<T> = NextObserver<T> | ErrorObserver<T> | CompletionObserver<T>;

A PartialObserver is a union type, and can either be a NextObserver, ErrorObserver, or CompletionObserver. Each class definition includes a required method, and the remaining are optional:


export interface NextObserver<T> {
closed?: boolean;
next: (value: T) =>
void;
error?: (err: any) => void;
complete?: () => void;
}

export interface ErrorObserver<T> {
closed?: boolean;
next?: (value: T) => void;
error: (err: any) => void;
complete?: () => void;
}

export interface CompletionObserver<T> {
closed?: boolean;
next?: (value: T) => void;
error?: (err: any) => void;
complete: () => void;
}

The deprecated message was a bit confusing to dissect and solve, but by drilling into the code I was able to figure it out.

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Comments are not allowed for this entry.
All Content Copyright 2005, 2006, 2007, 2008, 2009 Jeffry Houser. May not be reused without permission
BlogCFC was created by Raymond Camden. This blog is running version 5.9.2.002.