Home > Net >  how to use Rxjs filter in angular along with BehaviorSubject
how to use Rxjs filter in angular along with BehaviorSubject

Time:02-18

I have an array that looks as follows.

data = [
    {
      id: 1,
      name: 'a',
      status: true,
    },
    {
      id: 1,
      name: 'b',
      status: true,
    },
    {
      id: 1,
      name: 'c',
      status: false,
    },
  ];

I have created BehaviorSubject by setting the initial value as the above array.

I want to get the array of data, which status should be true by using rxjs pipe operator. So, the filter process should happen before subscribing to the observable.

I have tried ith the following

 subject: BehaviorSubject<any> = new BehaviorSubject<any>(this.data);
  constructor() {
    this.getSubject()
      .pipe(filter((x) => x.status))
      .subscribe((res) => {
        console.log(res);
      });
  }

  getSubject() {
    return this.subject.asObservable();
  }

Expected output

   [
    {
      id: 1,
      name: 'a',
      status: true,
    },
    {
      id: 1,
      name: 'b',
      status: true,
    }]

CodePudding user response:

Your behaviour subject is returning an Array and rxjs filter is applied on observable not array. You need to apply filter after getting array from observable

this.getSubject()
  .pipe(map((arr) => arr.filter(x => x.status)))
  .subscribe((res) => {
    console.log(res);
  });

CodePudding user response:

You are emitting an array of values rather than the values one by one. You can use map to operate on the array. Also, you can call pipe directly on the subject.

  ngOnInit(): void {
    this.subject
      .pipe(map((x: any[]) => x.filter((x: any) => x.status)))
      .subscribe((res: any) => {
        console.log(res);
      });
  }

As a side note, you can convert an array directly to an observable using from and of.

of will emit the entire array when subscribed to.

  data$ = of(this.data);

  ngOnInit(): void {
    this.data$
      .pipe(map((x: any[]) => x.filter((x) => x.status)))
      .subscribe((res: any) => {
        console.log(res);
      });
  }

This logs:

Array [ {…}, {…} ]

from will emit the values one by one when subscribed to.

  data$ = from(this.data);

  ngOnInit(): void {
    this.data$.pipe(filter((x: any) => x.status)).subscribe((res: any) => {
      console.log(res);
    });
  }

This logs:

Object { id: 1, name: "a", status: true }
Object { id: 1, name: "b", status: true }
  • Related