Home:ALL Converter>Angular 6/7: Only fetch data from API once but display in two routes / views

Angular 6/7: Only fetch data from API once but display in two routes / views

Ask Time:2019-01-07T00:33:42         Author:atwright147

Json Formatter

I am new to Angular > v1 and I am trying to get my head around some concepts (coming from a React/Redux background).

I have a RESTful API I want to get data from the API and display it in view/route #1, then allow the user to drill-down and see further info in view/route #2 (using .filter() to get just the pertinent object).

However, I find that Angular is downloading the API data on every view/route change. How do you workaround this normally, do you workaround this or is there a different pattern Angular devs usually use?

// src/app/core/api-client.service.ts

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

@Injectable({
  providedIn: 'root'
})
export class ApiClientService {

  domains;

  constructor(private http: HttpClient) { }

  getDomains() {
    console.info(this.domains);
    if (this.domains && this.domains.length) {
      return this.domains;
    }
    this.domains = this.http.get<Array<any>>('http://192.168.33.11:3000/domains/list');
    return this.domains;
  }

  getHostCapabilities() {
    return this.http.get<Array<any>>('http://192.168.33.11:3000/host/capabilities');
  }
}

// src/app/components/domains-list/domains-list.component.ts

import { Component, OnInit } from '@angular/core';
import { ApiClientService} from '../../core/api-client.service';

@Component({
  selector: 'app-domains-list',
  templateUrl: './domains-list.component.html',
  styleUrls: ['./domains-list.component.scss']
})
export class DomainsListComponent implements OnInit {

  domains: any;

  constructor(private ApiClient: ApiClientService) {}

  ngOnInit() {
    this.ApiClient.getDomains().subscribe(data => this.domains = data);
  }

}

// src/app/components/domain-detail/domain-detail.component.ts

import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

import { ApiClientService } from '../../core/api-client.service';

@Component({
  selector: 'app-domain-detail',
  templateUrl: './domain-detail.component.html',
  styleUrls: ['./domain-detail.component.scss']
})
export class DomainDetailComponent implements OnInit, OnDestroy {
  domainUuid: any;
  domains: any;
  private sub: any;

  constructor(
    private ApiClient: ApiClientService,
    private route: ActivatedRoute
  ) {}

  ngOnInit() {
    // my attempt at caching (still unfamiliar with Rxjs)
    this.sub = this.route.params.subscribe(params => {
      this.domainUuid = params.uuid;
    });
    this.ApiClient.getDomains().subscribe(data => this.domains = data.filter(item => item.uuid === this.domainUuid));
  }

  ngOnDestroy() {
    this.sub.unsubscribe();
  }

}

Author:atwright147,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/54063625/angular-6-7-only-fetch-data-from-api-once-but-display-in-two-routes-views
Harun Yilmaz :

You can use shareReplay(1) to share the latest data with the new subscribers. But from what I understand from your code, you want to load domains only once. Therefore, you can call http request on service constructor and then share the data with domains observable like this:\n\nimport { Injectable } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport {Observable} from 'rxjs';\nimport {shareReplay} from 'rxjs/operators';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ApiClientService {\n\n domains: Observable<Array<any>>;\n\n constructor(private http: HttpClient) { \n this.domains = this.http.get<Array<any>>('http://192.168.33.11:3000/domains/list');\n }\n\n getDomains() {\n return this.domains.pipe(shareReplay(1));\n }\n\n getHostCapabilities() {\n return this.http.get<Array<any>>('http://192.168.33.11:3000/host/capabilities');\n }\n}\n",
2019-01-06T17:48:55
Geethanjana Nallaperumage :

Store data in browser local storage after getting them in first route. Then use that local storage data in next routes. (Yes, there is a security risk.)",
2019-01-06T18:44:49
yy