Home > Net >  Getting IDs from Array and passing into function Angular
Getting IDs from Array and passing into function Angular

Time:08-24

I am struggling with arrays in Angular.

This is the response I get from another function and I need to use

 [
        {
            id: 1
            name: Jane
            age: 22
        },
        {
            id: 2
            name: Joe
            age: 24
        },
        {
            id: 3
            name: Anna
            age: 27
        },
    ]

This response is stored in a variable

users: IUser[]=[]

I need to access every id from the user's array and pass it into another function.

I tried this:

list: IList[] = []

this.users.map(users => {
          this.service
            .someRandomFunctionINeed$(users.id)
            .subscribe(data => {
              if (data.length > 0) {
                this.list = data
              }
              console.log('inside', this.list)
            })
        })
        console.log('outside', this.list)

The problem is that the new list array is filled inside subscribe but outside of it is empty.

What am I doing wrong?

CodePudding user response:

If you need to perform an async function call for each user, and then access it after finishing all iterations, I would do the following:

  async yourFunction() {
    for (let user of this.users) {
      console.log(user);
      let observableData$ = this.service.someRandomFunctionINeed$(user.id);
      // make the code wait until the call finishes, to be able to access it in the next line
      const data: any = await firstValueFrom(observableData$);
      console.log('your data loaded here', data);
      if (data.length > 0) {
        this.list = data;
      }
      console.log('inside', this.list);
    }
    console.log('you can read the data from this line on', this.list);
  }

I changed the .map to a for loop (as you were not mapping the result of each iteration to anything), and made use of RxJS - firstValueFrom to transform the observable returned from your call into a Promise that I can await inside an async function.

CodePudding user response:

Is this what you want

  1. use from from , Turn an array, promise, or iterable into an observable

  2. mergeMap mergeMap, map id to API and emit values.

const { from, mergeMap, toArray, mergeAll, tap, of, delay } = rxjs;

const users = [1, 2, 3];

const api = (id) => {  // this.service.someRandomFunctionINeed$(users.id)
  const time = (Math.random()   .5) * 1000;
  console.log(`api ${id}, ${time} ms`)
  return of([`user ${id}`]).pipe(delay(time));
};

const list1 = [];
from(users).pipe(
  tap((id) => console.log('before mergeMap', id)),
  mergeMap((id) => api(id)),
  tap((data) => console.log('after mergeMap', data))
).subscribe({
  next: (data) => list1.push(...data),
  complete: () => console.log('complete', list1)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.5.6/rxjs.umd.min.js"></script>

forkJoin

const { from, mergeMap, toArray, mergeAll, tap, of, delay, forkJoin } = rxjs;

const users = [1, 2, 3];

const api = (id) => {  // this.service.someRandomFunctionINeed$(users.id)
  const time = (Math.random()   .5) * 1000;
  console.log(`api ${id}, ${time} ms`)
  return of([`user ${id}`]).pipe(delay(time));
};

const list2 = [];
forkJoin(users.map((id) => api(id).pipe(mergeAll()))).subscribe({
  next: (data) => list2.push(...data),
  complete: () => console.log('complete list2', list2)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.5.6/rxjs.umd.min.js"></script>

  • Related