Skip to content

Fetching Data from a Backend/API

In the previous lessons, we have seen glimpses of using the HttpClient to fetch data from a server. Now we are going to look at it in detail. This is a key part of building an application because it is what allows you to reach outside of your application and pull data in from some external source (as well as send data back to it).

Some applications may be entirely self contained, but many need to integrate with some kind of backend. As you will see, the type of backend does not particularly matter. It could be written in Java, Go, Rust, PHP, Node. It could use MySQL, PostgreSQL, a static JSON file, CouchDB, Redis, MongoDB or just about anything else. The general idea is that we will make a request to some external server, and it will send a response back to our application with the data we need.

A Simple Example

A lot of the time, we will get data back from servers in a JSON format. If you don’t already know what that is it would be worth doing some research, but the basic idea is that it is a string that represents data in the form of a JavaScript object (JSON stands for JavaScript Object Notation). That JSON response can then be converted into a real JavaScript object in our application.

A low friction way to experiment with pulling data into your application is to use the Reddit API. The great thing about the Reddit API is that it is publicly accessible and doesn’t require any kind of authorisation to access.

You can create a JSON feed of posts from subreddits simply by visiting a URL in the following format:

If you click on that link, you will see a JSON feed containing 10 submissions from the gifs subreddit, sorted by the hot filter. But… how do we get that JSON data from that URL into our Angular application?

The answer is to use the HttpClient service which is provided by Angular and allows you to make HTTP requests. If you’re not familiar with what an HTTP request is, basically every time your browser tries to load anything (a document, image, a file etc.) it sends an HTTP request to do that. We can make an HTTP request to a page that spits out some JSON data, and pull that into our application.

Let’s do that now, but remember if you are following along that you will need to add provideHttpClient to app.config.ts file first:

import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient } from '@angular/common/http';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes),
provideHttpClient(),
],
};

Now let’s take a look at how we might make a request to a reddit URL:

import { JsonPipe } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { Component, inject } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
@Component({
selector: 'app-home',
template: ` <pre>{{ redditData() | json }}</pre> `,
imports: [JsonPipe],
})
export class HomeComponent {
private http = inject(HttpClient);
redditData = toSignal(
this.http.get('https://www.reddit.com/r/gifs/new/.json?limit=10')
);
}

We use http.get to create a stream which, when subscribed to, will give us the response from the URL. Keep in mind that the toSignal helper function we are using here will subscribe to the http.get observable stream for us and convert the value to a signal, which we are displaying in the template. We also use the json pipe which just allows us to display data in a JSON format nicely in the template — this is just for debugging, it is not something you would do in a normal application.

We still haven’t got to discussing observable streams and reactive programming in detail yet, so I don’t want to go off topic here. However, I think it is useful to see a more practical case here. We don’t want to just display JSON in our application, we probably want to do something like display a list using this data.

This is how you could do that:

import { JsonPipe } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { Component, inject } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { map } from 'rxjs/operators';
@Component({
selector: 'app-home',
template: `
<ul>
@for (post of redditData(); track post.permalink){
<li>{{ post.data.title }}</li>
}
</ul>
`,
imports: [JsonPipe],
})
export class HomeComponent {
private http = inject(HttpClient);
redditData = toSignal(
this.http
.get('https://www.reddit.com/r/gifs/new/.json?limit=10')
.pipe(map((res: any) => res.data.children))
);
}

Again, we are using concepts here we haven’t covered yet. We will get to those, I just want to give you a sense of how HttpClient can be used to pull data into an application. I will explain what is happening here, but just know I don’t expect you to understand this if this concept is new to you.

We start with our observable stream returned from http.get:

this.http
.get('https://www.reddit.com/r/gifs/new/.json?limit=10')

However, if we subscribe to that now we are just going to get the full dump of data from Reddit containing a whole bunch of stuff we don’t need. We are only interested in the actual posts. This is why we do this:

.pipe(map((res: any) => res.data.children));

We map the response (which is an RxJS operator for modifying streams, not the standard map method on an array) to only return the data we need. This is specific to the Reddit API, but in the case of the Reddit API, the data we need is available inside of data.children so that is what we return from our mapping operation.

Now that the data will be returned in the format we want, we subscribe to pull the value out in the template using toSignal:

redditData = toSignal(
this.http
.get('https://www.reddit.com/r/gifs/new/.json?limit=10')
.pipe(map((res: any) => res.data.children))
);

Which we can then display in the template by looping over the values in the signal:

<ul>
@for (post of redditData(); track post.permalink){
<li>{{ post.data.title }}</li>
}
</ul>

Fetching Data without RxJS or HttpClient

You may recall when we discussed the resource API earlier that it provides a way to fetch data with just the native fetch API.

For reference, that would look something like this:

redditData = resource({
loader: () => fetch(`https://www.reddit.com/r/gifs/new/.json?limit=10`)
.then((res) => res.json());
});

It is far more common currently to use HttpClient in Angular, and resource is still new and experimental (meaning the API may change before it is stable). However, usage of fetch in Angular might become more common in the future.

Regardless of whether we are using fetch or HttpClient, the resource API is still useful to us as we can still use resource with HttpClient:

redditData = rxResource({
loader: () => this.http.get(`https://www.reddit.com/r/gifs/new/.json?limit=10`)
});

Fetching Data from your Own Server

We know how to pull in data using a JSON feed like the one provided by Reddit, but what if you want to pull in your own data? How can you go about setting up your own JSON feed?

Going into the detail of how to set up your own API is a bit beyond what I wanted to achieve with this lesson, but I would like to give you a high-level overview of how it’s done. Basically:

  1. Make a request from your Angular application to a URL on your server
  2. Fetch the data using whatever server-side language you prefer
  3. Output the required data in JSON format

For example, if you had a NodeJS/Express server that might look something like this:

const express = require('express');
const app = express();
app.get('/movies', function(req, res) {
res.json([
{
id: 1,
title: 'Dune'
},
{
id: 2,
title: 'Coco'
},
{
id: 3,
title: 'Soul'
}
]);
});
app.listen(3000, function(req, res) {});

This is an overly simplistic example — most likely your server would be connecting to a database to fetch data or something like that rather than just returning a static response, but it should demonstrate the point.

As I mentioned, you can use whatever language and whatever data storage mechanism you like to do this. Just grab whatever data you need, get it in JSON format, and then output it to the browser. You don’t even need a server, it could just be a static JSON file you are serving. You can even make an HTTP request to a static JSON file within your application (you can add it to your assets folder and make a request to it there — but this is read only).

Recap

    What needs to be injected in order to make an HTTP request?

    What is the correct syntax for making an HTTP request?