Angular DRF GET

Connecting an Angular App to a REST API (Part 4)

In this article you’ll learn how to connect an Angular app to a REST API.

This post is part of the Dockerized Django Back-end API with Angular Front-end Tutorial. Check out all the parts of the tutorial there.

In the last part of the tutorial, we’ve learned how to build an Angular app using Docker. In this blog post, you’ll learn how to consume the REST API in Angular.

To get the code to where we left off in the last blog post, use:

$ git checkout v1.6

Overview of the Default Angular AppComponent

Firstly, let’s look at the existing code in the angular-app directory.

The default Angular CLI application that we’ve created in the last blog post comes with one Angular component out-of-the-box, namely AppComponent.

Components are simply TypeScript classes with an HTML template and optional CSS. They are used for sections of the UI, e.g. navigation bar, sidebar, etc.

Let’s quickly explain the files that were created by default in the angular-app directory:

  • app.module.ts – think of it as a centralised place for everything in your app. Components, services, and modules that you create need to be added to the @NgModule directive:
    • components go to declarations.
    • modules go to imports.
    • services go to providers.
    • bootstrap includes just the main (root) component, i.e. AppComponent.
  • app.component.ts
    • the selector identifies how the component can be referenced in HTML, the templateUrl points to a HTML file, and styleUrls points to a CSS file.
  • app.component.spec.ts – file used for tests.
  • app.component.html – this is the actual template which tells Angular how to render the component.
  • app.component.css – CSS for the template.

Creating an Angular Component

Now that we have an overview of the existing Angular files, let’s build an Angular component in order to create a basic UI that allows the user to see a list of Todo items.

Navigate to the angular/angular-app directory and run from the terminal:

$ ng generate component task-list

You’ll notice a new task-list directory was generated under angular-app/src/app. This directory contains the files for the TaskListComponent. Additionally, the component was automatically added to the declarations directive in src/app/app.module.ts.

In task-list.component.ts, there is an ngOnInit() method. This is a lifecycle hook that runs when a component is initialised.

Next, let’s check that the generated component works. We’ll need to reference the component using the selector found in task-list.component.ts, namely app-task-list.

Edit the src/app/app.component.html file and replace its contents with:

If you now go to http://localhost:4200/, you’ll see that the task-list works! message will be displayed. This is simply the default template found in task-list/task-list.component.html.

Default Angular component template

To get the code to this stage, run:

$ git checkout v1.7

Generate an Angular Service to Call the API

In this section, we’ll proceed to generate an Angular service that will connect to the DRF REST API.

In Angular a service is a class that provides reusable functionality across components. Generally, a service is a Singleton, meaning they will “live” as long as our application lives.

In most cases, you can think of components to be concerned with pieces of the UI, whereas services can be delegated tasks by components. These tasks can include fetching data from a server, dealing with input validation, or logging app data.

Let’s create a new service for calling the API. From the angular-app directory, run the command:

$ ng generate service api

The command will create the files api.service.ts and api.service.spec.ts in the angular-app/src/app directory. The first contains the service code, while the latter contains testing code.

For making HTTP requests in Angular, we’ll use the HTTPClient module. Import it and add it to the imports directive in app.module.ts:

Import and inject the HttpClient class in the service src/app/api.service.ts:

Creating a Task Interface

In TypeScript, we can use an interface for type-checking purposes. Basically, an interface just defines the properties of an object and their type. Let’s make a Task interface to define how a task object looks like.

Create a new file in src/app/ called task.ts.

GETting the Tasks from the API

Let’s retrieve the Todo tasks by making a GET request to the /api/task/ endpoint.

We’ll do this in three steps:

  1. Create a method in the API service to query the endpoint.
  2. Call the method from the TaskListComponent class.
  3. Display the returned tasks in the component template.

1. Create a method in the API service to query the endpoint

Edit src/app/api.service.ts and add the following:

Here, we can see that the getTasks() method returns an Observable, which we import from RxJS (Reactive Extensions for JavaScript).

Observables are a way of message passing in a publisher-subscriber model in an application. They are useful for processing asynchronous data streams, such as data received from calling an API.

Lastly, the Observable itself emits arrays of Task items, hence the typing Observable<Task[]>.

2. Call the Method from TaskListComponent

Edit src/app/task-list/task-list.component.ts, inject the API service, and call the getTasks() method:

The $ at the end of tasks$ is a naming convention for Observables.

3. Display the Results in the Component Template

Next, we will display the tasks in the component template. Open src/app/task-list/task-list.component.html and add the code:

Using the async pipe, we can subscribe to an Observable and iterate over the array of values returned.

Enable CORS in DRF

If you now access the app, you’ll see in the browser console that there’s an error related to the CORS (Cross-Origin Resource Sharing) policy.

CORS error Django DRF

The problem is that the browser is only allowed to send/receive requests from http://localhost:4200, where we serve the Angular app. The browser blocks requests made to the Django DRF API, which is served on http://localhost:80, from the Docker container.

Fortunately, we can tell the browser to allow requests by employing the django-cors-headers package:

  1. Add django-cors-headers to django/requirements.txt:

  1. Next, add the corsheaders app to todoproj/settings.py:

  1. Then, add corsheaders.middleware.CorsMiddleware to the middleware list in todoproj/settings.py:

  1. Lastly, you need to specify a list of hosts that are allowed to make cross-site HTTP requests. Also in todoproj/settings.py, add the following at the end of the file:

Here, I’ve also added localhost:8080 in case we make the request from the Angular app served by the Docker container instead of the ng serve one.

You need to rerun docker-compose build in the repo root so django-cors-headers is installed in the Django Docker image. After, rerun docker-compose up as usual and migrate the database.

If you now visit http://localhost:4200, you’ll see the dummy Todo tasks being displayed:

Angular Dummy Tasks from API

To get the code to this point of the tutorial, run:

$ git checkout v1.8

Summary

In this part of the tutorial, we’ve learned how to connect our Angular app to our Django DRF REST API to retrieve the tasks from our Todo application. We’ve also been introduced to Angular components, services, and Observables.

In the next part, we’ll see how we can enhance our Angular app to handle creating and updating task items.

About the Author Dragos Stanciu

follow me on:

Subscribe

Like this article? Stay updated by subscribing to my weekly newsletter:

Leave a Comment: