4

I have the following code, in which I wanna override the next to have some custom logic. It doesn't work this way, but only works if the next is a property with an arrow function. What's the reason behind it?

export class Store<T> extends ReplaySubject<T | undefined> {
  next(value?: T) {
    console.log("do something in my code");
    super.next(value);
  }
}
export class Store<T> extends ReplaySubject<T | undefined> {
  next = (value?: T) => {
    console.log("do something in my code");
    super.next(value);
  };
}

https://stackblitz.com/edit/typescript-override-subject-next

  • Subjects can be `Observer` so it's kind of expected, but when it comes to `ReplaySubject` it doesn't seem to implement `SubjectLike`. So bit confused here... – Ramesh Thiruchelvam Feb 13 '21 at 07:06

2 Answers2

2

Today, I also end up extending ReplaySubject to get the last value. For that, I raised a PR- https://github.com/ReactiveX/rxjs/pull/6652/files but to workaround in my project meanwhile, I extended the ReplaySubject and the same happened with me; the next was not being overwritten.

I drove myself crazy that why this is happening. I jumped into the source code and saw that in the RxJS 6.x version, the next method id is being overwritten by function assignment- https://github.com/ReactiveX/rxjs/blob/6.6.7/src/internal/ReplaySubject.ts#L31 and that's why it's not getting overwritten.

Following the history of the same file, I found that this behaviour got changed in v7.x (7.0.0-beta.6 to be specific) in this commit- https://github.com/ReactiveX/rxjs/commit/f1dcada1e1838ffb01cd0dac60340c6fa068f3cf#diff-a287f66fc20bf26caa2f42935756aa6a094f400e91d6b4a388aee4e4e11675c4.

So you have to upgrade to RxJS 7.x version to make it work.

If you can't upgrade to 7.x version- here is the workaround-

export class Store<T> extends ReplaySubject<T | undefined> {

  private originalNext: any;

  constructor(bufferSize: number, windowTime: number) {
    super(bufferSize, windowTime);
    this.originalNext = super.next;
    this.next = this.emit;
  }

  private emit(value?: T): void {
    console.log("do something in my code");
    super.next(value);
  };
}

Cheers!

Shashank Agrawal
  • 25,161
  • 11
  • 89
  • 121
1

Subject (and Observables) takes an Observer object with methods like next:

const observer = {
  next: () => {},
  error: () => {},
  complete: () => {},
};

You can provide this object to the Subject (preferably Observable) instead of extending it:

const subject = new Subject();

const observer = {
  next: (val) => { ... custom logic };
  < ... > 
}

subject.asObservable().subscribe(observer);
Julius Dzidzevičius
  • 10,775
  • 11
  • 36
  • 81