Andrew Howard
Andrew Howard

Reputation: 3072

Argument when using .next() with takeUntil

I've noticed recently after upgrading my rxjs version that you can't use the .next() method this.ngUnsubscribe$.next(); as it is anymore as you would below:

export class TakeUntilComponent implements OnDestroy {
  // Our magical observable that will be passed to takeUntil()
  private readonly ngUnsubscribe$: Subject<void> = new Subject<void>();

  // Our subject that we will subscribe to
  subjectA$: Subject<number> = new Subject<number>();

  constructor() {
    this.subjectA$
      .pipe(takeUntil(this.ngUnsubscribe$))
      .subscribe(value => {
      // logic goes here ...
    });
  }

  ngOnDestroy(){
    // Emit a value so that takeUntil will handle the closing of our subscriptions;
    this.ngUnsubscribe$.next();
    // Unsubscribe from our unsubscriber to avoid creating a memory leak
    this.ngUnsubscribe$.unsubscribe();
  }

}

But now you must send an argument to it like this:

this.ngUnsubscribe$.next(null);

or

this.ngUnsubscribe$.next(true);

My question is why? And what value would you know to send?

Upvotes: 12

Views: 15342

Answers (3)

user11006286
user11006286

Reputation:

Another approach to fix this would be to use the ng-neat npm package: https://github.com/ngneat/until-destroy

Just by adding @UntilDestroy({ checkProperties: true }) to the top of your class you can remove all the takeUntils(this.unsubscribe) out of the code and remove the ngOnDestroy method. Just think it looks a lot cleaner and you will have less imports.

Upvotes: 0

eko
eko

Reputation: 40647

This happens after upgrading rxjs version to 7 from 6

Rxjs 7 changes

After checking the changelog and several github issues about this situation,

Subject: resolve issue where Subject constructor errantly allowed an argument (#5476) (e1d35dc)

Subject: no default generic (e678e81)

Changelog 7.0.0-beta.1 and the commit where empty value is removed from the tests

enter image description here

I realized that the solution was to either provide a value or simply typecast the Subject with <void> (as @martin also said) as in destroy$ = new Subject<void>() if you want to next it with an empty value.

My related post: rxjs 7 update - Subject - Expected 1 arguments, but got 0

Upvotes: 21

martin
martin

Reputation: 96889

You're defining your Subject as Subject<void>. Calling next() wants to emit undefined.

So you should call this.ngUnsubscribe$.next(void 0) instead.

Upvotes: 14

Related Questions