user643317
user643317

Reputation: 41

Verify objects in array also exist in observable array

I would like to verify that the objects in the following array:

const payment1: Payment = new Payment('1000'); // 1000 = id
const payment2: Payment = new Payment('1001');

const paymentArray: Payment[];
paymentArray.push(payment1, payment2);

exist in my observable array:

payments$: Observable<Payment[]>;

What i would like is to get a non observable boolean as result.

I have tried somethings with filter pipe and map but unfortunately cant get it to work:

this.paymentArray.forEach(element => {
  this.payments$.pipe(map(payments => payments.filter(payment => payment.id === element['id'])));
});

Upvotes: 2

Views: 1534

Answers (4)

31piy
31piy

Reputation: 23869

You just need to pipe through the observable and map the stream. In the callback of map, check if every item paymentArray exists in the value.

See the following example:

const ids = paymentArray.map(p => p.id);

this.payments$.pipe(
  map(payments => {
    const paymentIds = payments.map(p => p.id);
    return ids.every(id => paymentIds.includes(id));
  })
)
// `value` should print `true` or `false` based on the checks.
.subscribe(value => console.log(value));

Upvotes: 1

rijin
rijin

Reputation: 1757

if its array of objects, create a map of those elements to compare it in filter function.

ngOnInit() {

    this.idsToFind = ['1000', '1231', '2323'];
    const paymentArray: Payment[] = [];
    const payment1: Payment = new Payment('1000'); // 1000 = id
    const payment2: Payment = new Payment('1001');

    paymentArray.push(payment1, payment2);

    this.payments$ = of(paymentArray);

    const idsMap = this.idsToFind.reduce(
      (a, b) => { return { ...a, [b]: true } }, {}
    );
    console.log(idsMap);

    this.payments$
      .pipe(
        map((payments) =>
          payments.filter(
            (payment: Payment) => idsMap[payment.id])
        )
      )
      .subscribe((missings) => console.log(missings));

  }

Upvotes: 1

Stanislav Dontsov
Stanislav Dontsov

Reputation: 1741

You can use toPromise to get observable result, like this:

const payment1: string = '1000';
const payment2: string = '1001';

const paymentArray: string[] = [];
paymentArray.push(payment1, payment2);

const payments$ = of(['1000', '1001', '1002']);

const allExist = await from(paymentArray).pipe(withLatestFrom(payments$), every(([item, payments]) => payments.includes(item))).toPromise();

Upvotes: 1

Ben
Ben

Reputation: 742

You can do something like this, see also my stackblitz link: https://stackblitz.com/edit/angular-yg1b11

import { Component, OnInit } from '@angular/core';
import { Observable, of } from 'rxjs';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  payments$: Observable<Payment[]>;
  idToFind = '';
  isFounded = false;

  ngOnInit() {

    this.idToFind = '1000'
    const paymentArray: Payment[] = [];
    const payment1: Payment = new Payment('1000'); // 1000 = id
    const payment2: Payment = new Payment('1001');

    paymentArray.push(payment1, payment2);

    this.payments$ = of(paymentArray);

    this.payments$.subscribe((x) => {
      x.forEach(element => {
        if (element.id == this.idToFind) {
          this.isFounded = true;
        }
      })
    })

  }

}

export class Payment {
  id: string;

  constructor(id: string) {
    this.id = id;
  }

}

Upvotes: 1

Related Questions