Description
Bug Report
Current Behavior
switchMap
(and other mapping operators) might not work correctly in Module Federation environment.
Code like:
this
.getSomeObservable()
.pipe(
switchMap(() => this.getOtherObservable()) // switching here causes the error
).subscribe()
Will cause : You provided an invalid object where a stream was expected error in Module Federation environment
exception
Expected behavior
Mapping operators should work and recognise
Reproduction
I was not able yet to reproduce it with a repo I could publicly push. This is explanation from the app I'm maintaining.
I've migrated one app to MFE Architecture using Module Federation and mysteriously looking error is thrown at runtime:
You provided an invalid object where a stream was expected error. You can provide an Observable, Promise, Array, or Iterable
.
The code that causes it looks like this:
this
.getSomeObservable()
.pipe(
switchMap(() => this.getOtherObservable()) // switching here causes the error
).subscribe()
However I was pretty sure code was ok...
When analysing stack trace, error originates from:
https://github.com/ReactiveX/rxjs/blob/6.6.7/src/internal/util/subscribeTo.ts
export const subscribeTo = <T>(result: ObservableInput<T>): (subscriber: Subscriber<T>) => Subscription | void => {
if (!!result && typeof result[Symbol_observable] === 'function') {
return subscribeToObservable(result as any);
} else if (isArrayLike(result)) {
return subscribeToArray(result);
} else if (isPromise(result)) {
return subscribeToPromise(result as Promise<any>);
} else if (!!result && typeof result[Symbol_iterator] === 'function') {
return subscribeToIterable(result as any);
} else {
const value = isObject(result) ? 'an invalid object' : `'${result}'`;
const msg = `You provided ${value} where a stream was expected.`
+ ' You can provide an Observable, Promise, Array, or Iterable.';
throw new TypeError(msg);
}
};
In my case, result
is of type BehaviorSubject
.
However, when I compared stack trace when app is running in non-federated to federated, the issue is here:
https://github.com/ReactiveX/rxjs/blob/6.6.7/src/internal/innerSubscribe.ts#L110
if (result instanceof Observable) {
return result.subscribe(innerSubscriber);
}
Without module federation, this if
is truthy, when I look at prototypes, deeper I can find Observable
.
However in federated environment, this expression is falsy.
The good news it that refactoring to:
this
.getSomeObservable()
.subscribe(() => this.getOtherObservable().subscribe())
does not throw error any more.
Environment
- RxJS version: 6.6.7
- Build configuration: webpack@5.50.0