I have an issue where data from my API is not being shown in the view source of my project. I did some research and came across the TransferState so I created a class:
import { Injectable } from '@angular/core';
import { TransferState } from '@angular/platform-browser';
import { Observable, from } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { tap } from 'rxjs/operators';
@Injectable({
providedIn: 'root',
})
export class TransferHttpService {
constructor(
private transferHttp: TransferState,
private httpClient: HttpClient
) {}
get(url, options?): Observable<any> {
return this.getData(url, options, () => {
return this.httpClient.get(url, options);
});
}
post(url, body, options?): Observable<any> {
return this.getData(url, options, () => {
return this.httpClient.post(url, body, options);
});
}
delete(url, options?): Observable<any> {
return this.getData(url, options, () => {
return this.httpClient.delete(url, options);
});
}
put(url, body, options?): Observable<any> {
return this.getData(url, options, () => {
return this.httpClient.put(url, body, options);
});
}
getData(url, options, callback: () => Observable<any>): Observable<any> {
const optionsString = options ? JSON.stringify(options) : '';
let key = `${url + optionsString}`;
try {
return this.resolveData(key);
} catch (e) {
console.log('In catch', key);
return callback().pipe(
tap((data) => {
console.log('cache set', key);
this.setCache(key, data);
})
);
}
}
resolveData(key) {
let resultData: any;
if (this.hasKey(key)) {
resultData = this.getFromCache(key);
console.log('got cache', key);
} else {
throw new Error();
}
return from(Promise.resolve(resultData));
}
setCache(key, value) {
this.transferHttp.set(key, value);
}
getFromCache(key) {
return this.transferHttp.get(key, null); // null set as default value
}
hasKey(key) {
return this.transferHttp.hasKey(key);
}
}
And in any service where I was using HttpClient, I now replaced with TransferHttpService instead. If you look at the service, you can see a few console logs. This is useful because when the data is grabbed from the cache, I can see it in View Page Source but if it has to insert it into the cache, then it's not in the page source.
When I first tested it, all seemed to be fine. I got this:
In my project console I could see this:
Which is great. But it doesn't seem to work all the time. If I refresh the page, sometimes it works, most of the time it doesn't:
In this case, the navigation and footer are both cached, but the pages isn't which means it isn't in the View Page Source.
Sometimes it's much worse, where all of the items are not cached:
And in that case, nothing is in the View Page Source.
What can I do to make sure the requests are always cached? Do I need to create a resolver or is it something more simple?
This was caused by two issues. The first was because I was using contentfuls SDK and out of the box it uses
HttpClient
, which actually needed overriding to use theTransferHttpService
(see here)The second issue was the
TransferHttpService
itself. I changed it to this:Which is a much better version and now everything works