Subject call to next causing a strange error

Tags: ,



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.

Answer

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.



Source: stackoverflow