my code: https://stackblitz.com/edit/rxjs-fgzw2i?devtoolsheight=60&file=index.ts
export class myCalss {
sub$: BehaviorSubject<number>;
constructor() {
this.sub$ = new BehaviorSubject(0);
}
test() {
from([1,2,3,4]).subscribe(
this.sub$.next, // num => this.sub$.next(num)
console.log
)
}
}
It's my code. There is an error in the code, but I don't know why. Please let me know if there is any problem in this code. Especially when the value is passed inside the subscribe function, I am curious about the part where you want to pass the passed value to the sub$. Normally, i write code as follows.
num => this.sub$.next(num)
But I found out that I can write it like this, too, isn't it?
this.sub$.next
CodePudding user response:
You can't do that in this case, because your Subject
is of type <number>
. If i remember correctly as of rxjs 7
you can call this.sub$.next()
without argument but Subject
has to be of type <void>
. The only usage it has are the cases where emitted value does not have any importance, what has importance is the fact that the value was emitted, even if it is nothing
. As per docs, an example would be a reactive timer
, I can't see the point anyways, Why would you call it with empty argument, it's unclear to someone who has not seen the process of development. It causes problems when used in combination with takeUntil
. Also, this can fire compile error because of strict mode
. It should be
like below, well not like you can do it other way if the type is <number>
...
Anyways, you have set up a logic that emmits certain value, and that value should be treated somewhere in some way, but next()
without argument is used when emitted value does not matter. Even if you could use it, it is inadequate in this case.
Use
test() {
from([1, 2, 3, 4]).subscribe({
next: (data) => {
this.sub$.next(data);
},
});
}
or just
test() {
from([1, 2, 3, 4]).subscribe((data) => {
this.sub$.next(data);
});
}
CodePudding user response:
But I found out that I can write it like this, too, isn't it? this.sub$.next
Short answer: sadly, no. While this syntax is not wrong per se, you get an error because the scope of this
gets lost if you use this "high order function" syntax.
Long answer:
The class Subject
of the rxjs library uses the this
keyword at some point, so passing the function as a parameter to the subscribe
makes it to lose the right scope.
Consider this example:
class MockSubject {
next(value) {
console.log('A function not referring `this` ' value);
}
}
and here is an example of usage like you tried:
mockSubject = new MockSubject;
test() {
from([1, 2, 3, 4]).subscribe(
this.mockSubject.next, // num => this.sub$.next(num)
console.log,
);
}
This example doesn't get that error you get because the method next
of the class MockSubject
doesn't refer to the this
object. Of course, you can't know if a function in a class uses the this
keyword, so my advice is to just avoid that syntax.
(the complete example in a stackblitz forked from yours: https://stackblitz.com/edit/rxjs-1jrzbf?file=index.ts)
And as a final tip, don't use the subscribe method with two callbacks since this way is deprecated - use the PartialObserver
object instead like this:
{
next: num => this.sub$.next(num), // num => this.sub$.next(num),
error: console.log
}
CodePudding user response:
You can do:
export class MyCalss {
sub$: BehaviorSubject<number> = new BehaviorSubject(0);
number$ = from([1, 2, 3, 4]).pipe(
tap((num) => console.log),
tap((num) => this.sub$.next)
);
test() {
this.number$.subscribe();
}
}