You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Determine which Observable operators and extensions to include in angular core #4390
Now that #2974 has landed, we're exposing the "bare" RxNext Observable without any operators included. This is partially because including the main Rx import caused everything to explode (as it has a large amount of files) and partially to avoid bloating the core codebase with another ~125k of operators.
A core set of of them should be included, things like map, flatMap, flatMapLatest, take, filter, reduce, scan, merge, and toPromise. Additionally specific operators can be exposed for specific APIs - for example, Http should add retry and retryWhen (or some equivalent)
Alternately we could fix the build issue and simply bring in the entire Rx module for now, and pare it down as we move closer to production and begin to optimize.
edit: the ES6 version is ~250k for the complete unminiified Rx, roughly ~half of which is operators. For CJS, its ~350k with again roughly half being operators.
It would be nice to provide a minimum set of operators, as you've described, by default from Angular APIs that export Observables. And to allow users who'd like a different set of operators, they should be able to override an ObservableFactory binding with DI (name not important right now). So when overriding that binding, calling http.get() would return an observable with the operators I need.
Without es7 function bind support in TypeScript, I'd recommend just including the current RxJS 5 Core Operators. There are a lot, but frankly they're a subset, and they're things that people want.
If you really don't want to include those, you could just mirror the Rx.ts file and create your own "lite" version... But then you'll be stuck supporting requests for the other operators.
... So my recommendation is use Rx as-is. And come make arguments to have ones removed you don't think are "core" enough.
We had a meeting with @IgorMinar, @Blesh and @robwormald today to discuss this issue. We wanted to come to a solution that would allow us to keep the byte size of angular2 core small, and make it easy for Rx power-users to easily get useful operators.
My proposal was to use a "lite" Observable with only a subscribe method, and use DI and provide an ObservableFactory token that could be overwritten:
import{Observable}from'@reactivex/rxjs/Rx';// Bind the included factory to a full-featured Observable with default set of operatorsbootstrap(MyComponent,[bind(ObservableFactory).toValue(Observable)]);
@mhevery brings up the point that by requiring an injector, users could not take advantage of field assignment shorthand provided by TypeScript.
classMyComponent{someEvent=newEventEmitter();// EventEmitter couldn't use DI in this case, unless refactored to accept an Observable argument.}
My counter-argument to that is that if users wanted to instantiate their own Subjects/Observables, they could just import the one the same one they've already bound to ObservableFactory token, and just instantiate it themselves without DI. It's up to whomever is consuming the component's events to know the shape of the Observable being provided. The benefit of the DI binding should only be for the angular framework itself to produce the shape of Observable that the consumer would like.
However, there are still issues with type information with the DI approach. For angular APIs that say they return an Observable from Angular (Observable lite), any code that consumes such an Observable would not automatically know that the binding had been replaced with a new shape of Observable.
Another discussion topic that came up was strategies for composing operators. Right now it's possible to compose operators onto an Observable instance using the lift method. The current RxJS design is prototype-based, so monkey-patching or extending are the way to add default operators.
Random notes, I know, but wanted to get them out there before I forget.
So to be clear, the lift method allows you to use an Operator from RxJS, which is a Subscriber factory to chain operators, but it's very unergonomic to do so.
One could either:
Decorate the prototype
Subclass Observable, overriding lift to return the Subclass, and add whatever operators you care about to that.
Use ES7 function bind, which is available in Babel, but not TypeScript.
I think if you had an ObservableFactory create your Observable class for you, you could have that be responsible for decorating the Observable.prototype. I don't know enough about Angular's current DI, but I presume it can dynamically create classes to be injected, and not just object instances?
Moving this into 41, working on a simple solution to manually add the combinators we need to EventEmitter without changing anything about its inheritance.
Activity
PatrickJS commentedon Sep 28, 2015
can you also include
Observable.ofandObservable.defer?jeffbcross commentedon Sep 28, 2015
It would be nice to provide a minimum set of operators, as you've described, by default from Angular APIs that export
Observables. And to allow users who'd like a different set of operators, they should be able to override anObservableFactorybinding with DI (name not important right now). So when overriding that binding, callinghttp.get()would return an observable with the operators I need.jeffbcross commentedon Sep 28, 2015
If we include an
Observablefactory in DI, it's worth considering whether the same should be done forPromise.gkalpak commentedon Sep 28, 2015
👍 and 👍 (1 for
Observableand 1 forPromisefactory).mhevery commentedon Sep 29, 2015
I would vote to not include any in Angular2 and have people import what they need.
robwormald commentedon Sep 29, 2015
Problem with that is at the moment there's not really a good way to add them after the fact to Observables returned from the core, at least in TS:
The ES7 functionBind proposal gives us a nice solution, but its not currently supported in TS:
Dart has a distinct advantage here as they provide a similar set in the language itself on Streams:
https://api.dartlang.org/1.12.1/dart-async/Stream-class.html#instance-methods
benlesh commentedon Sep 30, 2015
Without es7 function bind support in TypeScript, I'd recommend just including the current RxJS 5 Core Operators. There are a lot, but frankly they're a subset, and they're things that people want.
If you really don't want to include those, you could just mirror the Rx.ts file and create your own "lite" version... But then you'll be stuck supporting requests for the other operators.
... So my recommendation is use Rx as-is. And come make arguments to have ones removed you don't think are "core" enough.
benlesh commentedon Sep 30, 2015
FWIW, the ones in RxJS 5 Core are ones that are non-trivial to reproduce with any combination of other operators. That's the goal at least.
Most of them were chosen because of their usage within Netflix apps.
jeffbcross commentedon Oct 5, 2015
We had a meeting with @IgorMinar, @Blesh and @robwormald today to discuss this issue. We wanted to come to a solution that would allow us to keep the byte size of angular2 core small, and make it easy for Rx power-users to easily get useful operators.
My proposal was to use a "lite" Observable with only a
subscribemethod, and use DI and provide an ObservableFactory token that could be overwritten:@mhevery brings up the point that by requiring an injector, users could not take advantage of field assignment shorthand provided by TypeScript.
My counter-argument to that is that if users wanted to instantiate their own Subjects/Observables, they could just import the one the same one they've already bound to
ObservableFactorytoken, and just instantiate it themselves without DI. It's up to whomever is consuming the component's events to know the shape of theObservablebeing provided. The benefit of the DI binding should only be for the angular framework itself to produce the shape ofObservablethat the consumer would like.However, there are still issues with type information with the DI approach. For angular APIs that say they return an Observable from Angular (Observable lite), any code that consumes such an Observable would not automatically know that the binding had been replaced with a new shape of
Observable.Another discussion topic that came up was strategies for composing operators. Right now it's possible to compose operators onto an
Observableinstance using theliftmethod. The current RxJS design is prototype-based, so monkey-patching or extending are the way to add default operators.Random notes, I know, but wanted to get them out there before I forget.
Did I miss or misrepresent anything @Blesh @robwormald @IgorMinar?
benlesh commentedon Oct 5, 2015
So to be clear, the
liftmethod allows you to use anOperatorfrom RxJS, which is aSubscriberfactory to chain operators, but it's very unergonomic to do so.One could either:
liftto return the Subclass, and add whatever operators you care about to that.I think if you had an ObservableFactory create your Observable class for you, you could have that be responsible for decorating the Observable.prototype. I don't know enough about Angular's current DI, but I presume it can dynamically create classes to be injected, and not just object instances?
19 remaining items
jeffbcross commentedon Oct 13, 2015
Moving this into 41, working on a simple solution to manually add the combinators we need to EventEmitter without changing anything about its inheritance.
angular-automatic-lock-bot commentedon Sep 7, 2019
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.