Typeahead documentation adjustments for rxjs 5.5

The Typeahead documentation should be adapted to the changes coming in rxjs 5.5.

For example:

search = (text$: Observable<string>) =>
    text$
      .debounceTime(200)
      .distinctUntilChanged()
      .map(term => term.length < 2 ? []
        : states.filter(v => v.toLowerCase().startsWith(term.toLocaleLowerCase())).splice(0, 10));
}

This does not compile anymore, and could be changed to:

search = (text$: Observable<string>) =>
    text$.pipe(
      debounceTime(200),
      distinctUntilChanged(),
      map(term => term.length < 2 ? []
        : states.filter(v => v.toLowerCase().startsWith(term.toLocaleLowerCase())).splice(0, 10)
      )
    );
}

1 possible answer(s) on “Typeahead documentation adjustments for rxjs 5.5

  1. I made some readings and experiments.

    Demo

    First of all: our demo. It currently uses 3 different ways to apply operators:

    • import 'rxjs/add/operator/debounceTime', followed by obs.debounceTime(...): this uses the “old” side-effect import, which is clearly not recommended anymore
    • import {debounceTime} from 'rxjs/operator/debounceTime', followed by debounceTime.call(...): this is the same style as used in ng-bootstrap itself.
    • import {debounceTime} from 'rxjs/operators', followed by obs.pipe(debounceTime(...)). This is what is recommended by RxJS now (see https://github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md#usage)

    The result is that the vendor bundle of our demo contains all the RxJS operators. The size of the bundle, on master, is 509 kB.

    Migrating all the usages to the recommended usage (using pipeable operators, and importing them all from rxjs/operators) does make the code consistent, and shows the best practices in the demo code. But it doesn’t significantly reduce the vendor bundle size: 507 kB.

    The guide about pipeable operators warns about larger bundle sizes when importing from rxjs/operators, and proposes two solutions:

    1. Importing each operator individually: import {debounceTime} from 'rxjs/operators/debounceTime'
    2. Apply a change to the Webpack configuration.

    The first solution is not a very good one, IMO. Indeed, it doesn’t use the officially recommended way of importing, and it doesn’t prepare us for the near future. Indeed RxJS 6 is coming, and doesn’t allow such deep imports of operators anymore. See https://github.com/ReactiveX/rxjs/blob/master/CHANGELOG.md#breaking-changes-3:

    Pipeable operators must now be imported from rxjs like so: import { map, filter, switchMap } from ‘rxjs/operators’;. No deep imports.

    I thus tried to apply the second solution (Webpack configuration change) in the demo and, 🎉 , the bundle size goes from 509 kB to 449K. Using source-map-explorer indeed shows a signficant reduction in size for the rxjs operators.

    Library

    The ng-bootstrap non-demo code consistently uses the following style: import {debounceTime} from 'rxjs/operator/debounceTime', followed by debounceTime.call(...).

    I find this less readable and idiomatic than the standard way of using pipeable operators. I thus tried to replace them by pipeable operators, importing from rxjs/operators as recommended. I then built ng-bootstrap, and used this build in one of my angular-cli based projects. The production bundle size generated by the CLI stays identical, and source-map-explorer shows only a few operators in the bundle. So I think it’s safe to use pipeable operators in the library code, too.

    Conclusion

    I plan to submit two PRs:

    • one for the demo, using pipeable operators and applying the webpack change, reducing the bundle size and showing “the good way”
    • one for the library code, using pipeable operators.