1

I have a function getData() that calls an API, processes the data, transforms, and saves it to a BehaviorSubject. Then returns the processed data as an observable using of().

getData()

getData(fId: string | null = null) {

    // get the data to tempItems with an API Call
    this.getDataFromAPI().subscribe(data => {
        this.tempItems = [data]
    })

    let items = cloneDeep(this.tempItems);

    // Separate the items by folders and files
    const a: Item[] = items.filter(item => item.type === 'a');
    const b: Item[] = items.filter(item => item.type !== 'b');

    const path: Item[] = [];
    //do some work

    // Create  data

    let data = {
        folders: a,
        files: b,
        path
    }

    // Add this data to the BehaviorSubject
    this._items.next(data);

    return of(data);
}

getDataFromAPI()

    getDataFromAPI() {
    return this._httpClient.get(URL);
}

In the getData() function the variable this.tempItems is undefined in run time. Because of the HTTP call, the rest of the script is not waiting for the HTTP request to be finished.

How can I properly use Async Await here? and still, manage to return the of(data)

The function which call the getData() function expects an observable in return

Lenzman
  • 1,177
  • 18
  • 30
  • the function which call the `getData()` function expects an observable in return – Lenzman Jul 17 '21 at 11:05
  • Does this answer your question? [How do I return the response from an Observable/http/async call in angular?](https://stackoverflow.com/questions/43055706/how-do-i-return-the-response-from-an-observable-http-async-call-in-angular) – R. Richards Jul 17 '21 at 13:02
  • Not really. I am using this service with resolver. And accessing the data from the BehaviourSubject in `ngOnInit` – Lenzman Jul 17 '21 at 13:25

2 Answers2

1

You can use operators like this:

getData(fId: string | null = null) {

    return this.getDataFromAPI().pipe(
        tap(data => {
            this.tempItems = [data]
        }),
        map(data => {
             let items = cloneDeep([data]);

             // Separate the items by folders and files
             const a: Item[] = items.filter(item => item.type === 'a');
             const b: Item[] = items.filter(item => item.type !== 'b');

             const path: Item[] = [];
             //do some work

            // Create  data

            return {
                folders: a,
                files: b,
                path
            };
        }),
        tap(data => {
              this._items.next(data);
        })
    );
}
  • tap is used to apply side effects and doesn't change the emitted value
  • map is used to transform the emitted value
Gaël J
  • 11,274
  • 4
  • 17
  • 32
0

use async/ await and promise on your API function

 async getDataFromAPI() 
  {
    return   { await  this._httpClient.get(URL).toPromise() }
  }