From af32e48bffec2f909f184c365323bd7115d43f6f Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Fri, 4 Feb 2022 17:13:12 -0600 Subject: [PATCH] fix(subscribe): allows functions where bind has been patched to be weird Apparently, code exists in the wild that will patch function bind to do something other than return a function that will execute the function instance, so we cannot rely on bind. Resolves #6783 --- spec/Observable-spec.ts | 28 ++++++++++++++++++++++++++++ src/internal/Subscriber.ts | 6 +++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/spec/Observable-spec.ts b/spec/Observable-spec.ts index 630cd5085d..672a724c6b 100644 --- a/spec/Observable-spec.ts +++ b/spec/Observable-spec.ts @@ -191,6 +191,34 @@ describe('Observable', () => { }); describe('subscribe', () => { + it('should work with handlers with hacked bind methods', () => { + const source = of('Hi'); + const results: any[] = []; + const next = function (value: string) { + results.push(value); + } + next.bind = () => { /* lol */}; + + const complete = function () { + results.push('done'); + } + complete.bind = () => { /* lol */}; + + source.subscribe({ next, complete }); + expect(results).to.deep.equal(['Hi', 'done']); + }); + + it('should work with handlers with hacked bind methods, in the error case', () => { + const source = throwError(() => 'an error'); + const results: any[] = []; + const error = function (value: string) { + results.push(value); + } + + source.subscribe({ error }); + expect(results).to.deep.equal(['an error']); + }); + it('should be synchronous', () => { let subscribed = false; let nexted: string; diff --git a/src/internal/Subscriber.ts b/src/internal/Subscriber.ts index de010710d3..5413f40e01 100644 --- a/src/internal/Subscriber.ts +++ b/src/internal/Subscriber.ts @@ -166,9 +166,9 @@ export class SafeSubscriber extends Subscriber { } else { context = observerOrNext; } - next = next?.bind(context); - error = error?.bind(context); - complete = complete?.bind(context); + next = next && ((value: T) => context.next(value)); + error = error && ((err: any) => context.error(err)); + complete = complete && (() => context.complete()); } // Once we set the destination, the superclass `Subscriber` will