Understanding Operator Imports
This adds the imported operator to the prototype for use throughout your project:
import { Observable } from '../../Observable';
import { take } from '../../operator/take';
Observable.prototype.take = take;
declare module '../../Observable' {
interface Observable<T> {
take: typeof take;
}
This method is generally OK for private projects and modules, the issue arises when you are using these imports in say, an package or library to be consumed throughout your organization.
To see where a problem can spring up, let’s imagine Person A is creating a public Angular component library. In this library you need a few operators so you add the typical imports:
some-public-library.ts
import 'rxjs/add/operator/take';
import 'rxjs/add/operator/concatMap';
import 'rxjs/add/operator/switchMap';
A month later Person A decides to update their library. They no longer need or concatMap
so they remove the imports:
some-public-library.ts
Person B upgrades the dependency, builds their project, which now fails. They never included switchMap
or concatMap
themselves, it was just working based on the inclusion of a 3rd party dependency. If you were not aware this could be an issue it may take a bit to track down.
Instead of importing operators like:
import 'rxjs/add/operator/take';
We can instead import them like:
import { take } from 'rxjs/operator/take';
This quickly gets ugly however, imagine we have a longer chain:
import { take } from 'rxjs/operator/take';
import { map } from 'rxjs/operator/map';
import { of } from 'rxjs/observable/of';
map.call(
take.call(
of(1,2,3),
),
val => val + 2
);
Pretty soon we have a block of code that is near impossible to understand. How can we get the best of both worlds?
RxJS now comes with a pipe
helper on Observable
that alleviates the pain of not having operators on the prototype. We can take the ugly block of code from above:
import { take, map } from 'rxjs/operators';
import { of } from 'rxjs/observable/of';
map.call(
take.call(
of(1,2,3),
2
),
And transform it into:
Much easier to read, right? This also has the benefit of greatly reducing the RxJS bundle size in your application. For more on this, check out excellent article Reduce Angular app bundle size using lettable operators.