When I build the portfolio section on the personal website, I was thinking that it is a good thing that I should get data from Github, in order to show my “proud” repositories and I don’t have to worry about updating any info on the frontend because Github will do it for me automatically.

Everything went really well until one day, I discovered something interesting which lead to this article on how to cache HTTP request with Rxjs.

The Problem

Every time, I navigate through the page, it will send another request. Sometimes, there’re errors because it hits the limits of the GitHub API.

The original method was using HttpClient service in order to send a request and get the projects from Github. It’s because every time I come back to the home page, the Http request will be retriggered again.

// Before getGitProjects() {

const filteredProjects = [];

try {

const projects = await this.http.get(this.gitBaseUrl).toPromise() as GitProject[];

for (const project of projects) {

if (this.gitProjects.includes(project.name)) {

const mappedProject: GitProject = {

name: project.name,

description: project.description,

html_url: project.html_url,

language: project.language,

stargazers_count: project.stargazers_count,

forks: project.forks

};

filteredProjects.push(mappedProject)

}

}

} catch (error) {

captureException(error)

console.error(error)

} return filteredProjects

}

This is not acceptable for my readers who will fetch data multiple times from an API. There should be a way to cache the result and use it. And RXJS has exactly just that — shareReplay.

// After getGitProjects(): void {

this.projects$ = this.http.get<GitProject[]>(this.gitBaseUrl).pipe(

map(projects =>

projects.filter(project => this.gitProjects.includes(project.name))

),

// publishReplay(1),

// refCount(),

shareReplay({ bufferSize: 1, refCount: true }),

catchError(error => captureException(error))

) as Observable<GitProject[]>

}

Explanation: With the usage of shareReplay. When I navigate back and forth to the home page, it will always return the last emitted value from the data stream. There is another interesting read about the magic of Rxjs that you should give it a read.

After optimization, whenever I navigate to other pages. It won’t send any other requests.

The result is satisfying.

Link to portfolio.service.ts

Hope this helps ;)