angularangular2-services

Store the first http request return value as global and be used for the following http request as parameter (Angular)


The following code is the situation I simulate, I want to first wait for the first http return result, then store becomes 1 (actually store is one of the return values in data, I will use 1 instead for brevity), and then the second http can continue to run only after receiving store as 1. But store is always 0, why is this? How can the second http service receive store as 1.

import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  name = 'Angular';
  apiUrl = 'https://www.techiediaries.com/api/data.json';
  store: number = 0;

  constructor(private httpClient: HttpClient) {}

  ngOnInit() {
    this.fetchData1();
    this.fetchData2(this.store);
  }

  private async fetchData1() {
    const data = await this.httpClient.get(this.apiUrl).toPromise();
    this.store = 1;
    console.log('Data: ' + JSON.stringify(data));
  }

  private async fetchData2(store) {
    if (store === 1) {
      const data = await this.httpClient.get(this.apiUrl).toPromise();
      console.log('Data: ' + JSON.stringify(data));
    }
  }
}

Here is the example: https://stackblitz.com/edit/angular-http-async-await-jt592p?file=src%2Fapp%2Fapp.component.ts,src%2Fapp%2Fapp.component.html


Solution

  • I have a partially completed stackblitz solve of what you trying to do.

    https://stackblitz.com/edit/angular-http-async-await-3my1vg?file=src%2Fapp%2Fapp.component.ts,src%2Fapp%2Fapp.component.html

    First things first. I would stick to observables.

    With observables you can cache the request by using shareReplay(1) in a pipe.

    export class AppComponent implements OnInit {
      name = 'Angular';
      apiUrl = 'https://www.techiediaries.com/api/data.json';
      data$: Observable<any>;
      
      // put this in a servivce
      cache$: Observable<any>;
    
      constructor(private httpClient: HttpClient) {}
    
      ngOnInit() {
        this.data$ = this.fetchData1();
        // fetch again
        this.data$ = this.fetchData1();
      }
    
      // put this in a service
      private fetchData1() {
        if (!this.cache$) {
          this.cache$ = this.httpClient.get(this.apiUrl).pipe(shareReplay(1));
        }
        return this.cache$;
      }
    }
    

    subscribing to it you just use the async pipe, (the json pipe is just to make sure it does not say [object object])

    <div>
      <p>
        {{ data$ | async | json }}
      </p>
    </div>
    

    If you check the network console. eventhough you request the data multiple times. it does not hit the network tab. it just stays in the object.

    You will have to move the request data and cache into a service. then you can use the same data anywhere in your application.