Veoxer
Veoxer

Reputation: 442

RxJS take() operator

I'm having a bit of trouble understanding the take() operator. In it's definition it is supposed to return the first value emitted by the observable but to me it seems like it's returning the last one.

I tried the following test to understand it better :

UsersService.ts

import {User} from '../models/user.model';
import {BehaviorSubject} from 'rxjs';

@Injectable({providedIn: 'root'})
export class UsersService {

  userObs = new BehaviorSubject<{test: string}>(null);

  testEmit(inp: string) {
    this.userObs.next({test: inp});
  }
}

and a component.

users.component.html

  <div class="row">
    <div class="col-xs-12 col-md-6 col-md-offset-3">
      <input type="text" class="form-control" #inp>
      <button class="btn btn-primary" (click)="testTake(inp)">Emit</button>
    </div>
  </div>
</div> 

users.component.ts

import {Component, Input, OnDestroy, OnInit} from '@angular/core';
import {User} from '../models/user.model';
import {UsersService} from '../services/users.service';
import {interval, Observable, Observer, Subscription} from 'rxjs';
import {take} from 'rxjs/operators';

@Component({
  selector: 'app-users',
  templateUrl: './users.component.html',
  styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit, OnDestroy {
  constructor(private usersService: UsersService) {
  }

  ngOnInit(): void {
    this.usersService.userObs.pipe(take(1)).subscribe((data: {test: string}) => {
      console.log(data.test);
    });
  }

  testTake(inp: HTMLInputElement) {
    this.usersService.testEmit(inp.value);
  }
}

In the view I type something in the input and I click the button to emit it and then I go to another component and come back to this one to retrigger the OnInit() function and what I get in the console is the last value I wrote in the input. Am I looking at this the wrong way?

Thank you for your time and help.

Upvotes: 0

Views: 860

Answers (1)

micronyks
micronyks

Reputation: 55443

That is very obvious as BehaviorSubject has the characteristic that it stores the “current” value. This means that you can always directly get the last emitted value from the BehaviorSubject.

And you are using singleton service. So when when you move to other route and come back, it gonna emit, last stored value.

This could help you to understand it further

If that is not what you want, I'd recommend to use Subject instead of BehaviourSubject.

Upvotes: 2

Related Questions