1

This causes the following error: Cannot read property 'length' of undefined

const msg$ = new Subject<string>();
msg$.subscribe(console.log)
of("Hello").subscribe(msg$.next);

If, however, I wrap msg$.next in a function, then it works without any errors.

  • Lambda function
const msg$ = new Subject<string>();
msg$.subscribe(console.log)
of("Hello").subscribe(greeting => msg$.next(greeting));
  • Anonymous function
const msg$ = new Subject<string>();
msg$.subscribe(console.log)
of("Hello").subscribe(function(greeting){
  msg$.next(greeting);
});
  • Named function
function nextMsg(greeting){
  msg$.next(greeting);
}
const msg$ = new Subject<string>();
msg$.subscribe(console.log)
of("Hello").subscribe(nextMsg);

They're all just wrapper functions that seemingly do nothing but call the next function. What's going on here? Seems like there's a JavaScript gotcha I'm not aware of at work here.

Mrk Sef
  • 7,557
  • 1
  • 9
  • 21
  • 2
    I think this question comes down to "What's the value of "this" when passing a function as parameter?". You might find some answers here [How to access the correct `this` inside a callback?](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback). `this` has the wrong value in your fist example. If you put a `console.log(this)` inside `nextMsg` you will see that it's a `SafeSubscriber` which lacks the property `observers.length` that is accessed. The `Subject.next` function in rxjs6 relies on `this` to be a `Subject` with a `observers.length` property. – frido Dec 01 '20 at 17:09
  • Yup, of course. Seems silly that I didn't notice. `msg$.next.bind(msg$)` works. `a.func` doesn't have `a` as a context, whereas `a.func()` does. If you put your comment as an answer, I'd accept that. – Mrk Sef Dec 01 '20 at 17:42
  • It will also work if you would use `source$.subscribe(subjectInstance)`. It will automatically call `subject.{next,error,complete}()`, depending on what `source$` emits. – Andrei Gătej Dec 01 '20 at 21:38

1 Answers1

0

Accepted answer for posterity's sake


I think this question comes down to "What's the value of "this" when passing a function as parameter?". You might find some answers here How to access the correct this inside a callback?.

this has the wrong value in your first example. If you put a console.log(this) inside nextMsg you will see that it's a SafeSubscriber which lacks the property observers.length that is accessed. The Subject#next function in rxjs6 relies on this to be a Subject with an observers.length property

Yup, of course. Seems silly that I didn't notice. msg$.next.bind(msg$) works.

obj.func doesn't have obj as a context, whereas obj.func() does.

Mrk Sef
  • 7,557
  • 1
  • 9
  • 21