Angular-cli: Documentation for using 'Pipeable' RxJs operators

Created on 13 Dec 2017  路  8Comments  路  Source: angular/angular-cli

I've asked this question first at SO, but I rarely have luck getting answers there. So please bare with me.

In Angular CLI versions <1.5.0 you could import your project's RxJs operators into a single file and use them throughout the application.

i.e.

rxjs-operators.ts

// Statics
import 'rxjs/add/observable/throw';
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/range';
import 'rxjs/add/observable/concat';
import 'rxjs/add/observable/merge';
import 'rxjs/add/observable/empty';

// Operators
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/toPromise';
...

app.module.ts

// OPERATORS
import './rxjs-operators';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [...],
  providers: [...],
  schemas: [
    CUSTOM_ELEMENTS_SCHEMA
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

With the encouraged usage of the RxJs pipe operator the import examples are always within the individual module it's used in.

i.e.

...
import { Observable } from 'rxjs/Observable';
import 'rxjs/util/pipe';
import { take, catchError  } from 'rxjs/operators';


@Injectable()
export class AccountDetailsResolver implements Resolve<AccountDetails> {
  constructor(private membersApi: MembersApiService,
              private router: Router,
              private navigationManager: NavigationManagerService) {}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<AccountDetails> {
    if(route.paramMap.get('accountId')) {
      return this.membersApi.getBasicDetails(route.paramMap.get('accountId')).pipe(
        catchError(error => {
          this.navigationManager.navigateToDefaultScreen();
          return Observable.of(null);
        }),
        take(1)
      );
    } else {
      return Observable.of(null);
    }
  }
}

I'm wondering if there's still a way to import all of these operators and static methods into one place or if it's necessary to include the import into each Angular definition for the Module, Component, Service, Pipe, Directive, etc.

Most helpful comment

@deebloo what about import bundle size. With default angular-cli build should we use
import { map, filter, reduce } from 'rxjs/operators';

or

import { map } from 'rxjs/operators/map';
import { filter } from 'rxjs/operators/filter';
import { reduce } from 'rxjs/operators/reduce';

?

All 8 comments

@denver-HJS with lettable operators just being functions you will have to import them into each file. The benefit of this is it is tree shakable and custom operators are much simpler to create. The downside is, as you pointed out, you have to import them individually as you need them.

@deebloo understood. Thanks for the reply.

@deebloo what about import bundle size. With default angular-cli build should we use
import { map, filter, reduce } from 'rxjs/operators';

or

import { map } from 'rxjs/operators/map';
import { filter } from 'rxjs/operators/filter';
import { reduce } from 'rxjs/operators/reduce';

?

@MattiJarvinen-BA As far as using the CLI, it should be safe to use the single import statement. But there appears to be a bug in Webpack that is causing the CLI to import all of the RXJS operators if you use any lettable operator imports.

Upgrading to lettable operators in CLI 1.6.3 caused RxJS to go from 60 KB to 122 KB for me. It sounds like a fix is 'coming soon', but I haven't been able to track down the issue to follow.

What about other operators, still not "lettable" ?

Ex:

import 'rxjs/add/operator/do';
Observable.from([1,2,3]).do(console.log)

edit: sorry I didn't find the doc firsthand because they are actually called pipeable operators

do has been renamed to tap, that's why I could not find it.

@colthreepv - yes, they've renamed them since this was OP.

For static operators I've taken the approach of using them this way (although admittedly I wonder if there's something better)

import { of as ObservableOf } from 'rxjs/observable/of';
...
if(cachedValue) {
  return ObservableOf(cachedValue);
}
...

So are we good with importing pipeable operators as one single import statement in Angular like,
import { map, filter, takeUntil } from 'rxjs/operators'?

I thought we better import them separately because the build process is not on our hand.

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings