Home > OS >  I want to know how to deliver the value from rxjs to the subject
I want to know how to deliver the value from rxjs to the subject

Time:05-21

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();
  }
}
  • Related