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();
}
}
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