It might sound silly, but I would spend some time away from the Angular bit defining the shape of the domain objects you’re dealing with. No more data, no more item, no more any.
export interface Treat {
id: string;
flavor: "sweet" | "savory";
calories?: number;
label: string;
}
export interface TreatBag {
id: string;
treats: Treat[]
}
Now get all the http junk out of the page and into a service that provides domain objects. If you have to massage what comes over the wire from the API, do it here. If you need other types of slices aside from “all available bags”, such as getBagById(), define it here.
Centralize all the business with API tokens and backend servers into an interceptor. An example that you should be able to adapt:
class AuthService {
peek(): Promise<string> {...}
}
class ServerService {
server: Promise<string>;
}
class AuthHttpInterceptor implements HttpInterceptor {
constructor(private auther: AuthService, private serverer: ServerService) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return from(Promise.all([this.serverer.server, this.auther.peek()])).pipe(
mergeMap(([server, jwt]) => {
let tochange: { url?: string, setHeaders?: { Authorization: string } } = {};
if (server) {
tochange.url = server + req.url;
}
if (jwt) {
tochange.setHeaders = {Authorization: "Bearer " + jwt};
}
let areq = req.clone(tochange);
return next.handle(areq);
}));
}
This uses JWT, but you can use HttpParams to throw things in the query string as you are doing now. Look at how amazingly streamlined this can make the service: everything that is currently being done in getData() collapses into a single simple line:
export class TreatService {
allTreatBags(): Observable<TreatBag[]> {
return this.http.get("collections");
}
}
Now that we can see the forest for the trees, we go back to the page and hopefully the path ahead is crystal clear:
export class TreatPage {
bags: TreatBag[] = [];
constructor(private treater: TreatService) {
this.treater.allTreatBags().subscribe(bags => this.bags = bags);
}
}
<ion-note *ngFor="let bag of bags">{{bag.treats.length}}</ion-note>
Next up we may have “what do I do when the page’s copy of the data gets stale?”, for which I would recommend this post.