Angular and RxJS: Create an API Service to Talk to a REST Backend — SitePoint

  • Part 0— The Ultimate Angular CLI Reference Guide
    Part 1— Getting our first version of the Todo application up and running
    Part 2— Creating separate components to display a list of todo’s and a single todo
    Part 3— Update the Todo service to communicate with a REST API
    Part 4— Use Angular Router to resolve data
    Part 5— Add authentication to protect private content

    In part one we learned how to get our Todo application up and running and deploy it to GitHub pages.

  • We will:
    create a mock REST API back-end
    store the API URL as an environment variable
    create an ApiService to communicate with the REST API
    update the TodoDataService to use the new ApiService
    update the AppComponent to handle asynchronous API calls
    create an ApiMockService to avoid real HTTP calls when running unit tests

    By the end of this article, you will understand:
    how you can use environment variables to store application settings
    how you can use the Angular HTTP client to perform HTTP requests
    how you can deal with Observables that are returned by the Angular HTTP client
    how you can mock HTTP calls to avoid making real HTTP request when running unit tests
    So, let’s get started!

  • By default, there are two environments: development and production, both with a corresponding environment file: and add our API URL to both files:
    // used when we run `ng serve` or `ng build`
    export const environment = {
    production: false,

    // URL of development API
    apiUrl: ‘http://localhost:3000’
    };

    // used when we run `ng serve –environment prod` or `ng build –environment prod`
    export const environment = {
    production: true,

    // URL of production API
    apiUrl: will later allow us to get the API URL from our environment in our Angular application by doing:
    import { environment } from we can now access environment.apiUrl
    const API_URL = environment.apiUrl;

    When we run ng serve or ng build, Angular CLI uses the value specified in the development environment when we run ng serve –environment prod or ng build –environment prod, Angular CLI uses the value specified in is exactly what we need to use a different API URL for development and production, without having to change our code.

  • Creating the Service to Communicate with the REST API
    Let’s use Angular CLI to create an ApiService to communicate with our REST API:
    ng generate service Api –module app.module.ts

    which gives the following output:
    installing service
    create src/app/api.

  • Implementing the ApiService Methods
    If we think back of the endpoints our REST API back-end exposes:

    GET /todos: get all existing todo’s

    GET /todos/:id: get an existing todo

    POST /todos: create a new todo

    PUT /todos/:id: update an existing todo

    DELETE /todos/:id: delete an existing todo
    we can already create a rough outline of methods we need and their corresponding Angular HTTP methods:

    import { Injectable } from ‘@angular/core’;
    import { environment } from { Http, Response } from ‘@angular/http’;
    import { Todo } from ‘.

Jurgen Van de Moere takes an existing Angular 2+ app and adds a REST API service. Learn about RxJS observables and how to mock HTTP services for testing.

@archana0685: #Angular and #RxJS: Create an API Service to Talk to a REST Backend #angularjs #javascript

This article is part 3 of the SitePoint Angular 2+ Tutorial on how to create a CRUD App with the Angular CLI.

In part one we learned how to get our Todo application up and running and deploy it to GitHub pages. This worked just fine but, unfortunately, the whole app was crammed into a single component.

In part two we examined a more modular component architecture and learned how to break this single component into a structured tree of smaller components that are easier to understand, re-use and maintain.

In this part, we will update our application to communicate with a REST API back-end.

You don’t need to have followed part one or two of this tutorial, for three to make sense. You can simply grab a copy of our repo, checkout the code from part two, and use that as a starting point. This is explained in more detail below.

A Quick Recap

Here is what our application architecture looked like at the end of part 2:

stores all data in memory. In this third article, we will update our application to communicate with a REST API back-end instead.

We will:

By the end of this article, you will understand:

So, let’s get started!

Up and Running

Make sure you have the latest version of the Angular CLI installed. If you don’t, you can install this with the following command:

If you need to remove a previous version of the Angular CLI, you can:

After that, you’ll need a copy of the code from part two. This is available at https://github.com/sitepoint-editors/angular-todo-app. Each article in this series has a corresponding tag in the repository so you can switch back and forth between the different states of the application.

The code that we ended with in part two and that we start with in this article is tagged as part-2. The code that we end this article with is tagged as part-3.

So, to get up and running (the latest version of the Angular CLI installed) we would do:

Then visit http://localhost:4200/. If all is well, you should see the working Todo app.

Setting up a REST API back-end

Let’s use json-server to quickly set up a mock back-end.

From the root of the application, run:

with the following contents:

to start our back-end:

We can now launch our REST API using:

which should display:

That’s it! We now have a REST API listening on port 3000.

The following endpoints are supported:

To learn more about json-server, make sure to check out mock REST API’s using json-server.

Storing the API URL

Now that we have our back-end in place, we must store its URL in our Angular application.

Ideally, we should be able to:

Let’s add our API URL to both files:

This will later allow us to get the API URL from our environment in our Angular application by doing:

This is exactly what we need to use a different API URL for development and production, without having to change our code.

by adding a key:

and creating the corresponding environment file.

To learn more about Angular CLI environments, make sure to check out the The Ultimate Angular CLI Reference Guide.

Now that we have our API URL stored in our environment, we can create an Angular service to communicate with the REST API.

to communicate with our REST API:

which gives the following output:

and inject our environment and Angular’s built-in HTTP service:

Before we implement the methods we need, let’s have a look at Angular’s HTTP service.

It is built on top of XHR/JSONP and provides us with an HTTP client that we can use to make HTTP requests from within our Angular application.

The following methods are available to perform HTTP requests:

Each of these methods returns an RxJS Observable.

In contrast to the AngularJS 1.x HTTP service methods, which returned promises, the Angular HTTP service methods return Observables.

Don’t worry if you are not yet familiar with RxJS Observables. We only need the basics to get our application up and running. You can gradually learn more about the available operators when your application requires them and the ReactiveX website offers fantastic documentation.

If we think back of the endpoints our REST API back-end exposes:

Let’s have a closer look at each of the methods.

getAllTodos()

method allows us to get all todos from the API:

First, we make a GET request to get all todo’s from our API:

This returns an Observable.

objects:

to parse the JSON string to its corresponding JavaScript value.

, not the RxJS operator.

Finally, we attach an error handler to log potential errors to the console:

We define the error handler in a separate method so we can reuse it in other methods:

Before we can run this code, we must import the necessary dependencies from the RxJS library:

, it is recommended to only import the pieces you require. This will substantially reduce the size of your resulting code bundle to a minimum.

class:

and import the three operators that our code requires:

Importing operators ensures that our Observable instances have the corresponding methods attached to them.

in our code, then the following would not work:

method.

We only have to import the operators once to enable the corresponding Observable methods globally in your application. However, importing them more than once is not a problem and will not increase the resulting bundle size.

getTodoById()

method allows us to get a single todo:

We don’t need this method in our application, but it is included to give you an idea of what it would look like.

createTodo()

method allows us to create a new todo:

We first perform a POST request to our API and pass in the data as the second argument:

object:

method allows us to update a single todo:

We first perform a PUT request to our API and pass in the data as the second argument:

object:

method allows us to delete a single todo:

We first perform a DELETE request to our API:

We don’t really need to transform the response here and could leave out this line. It is just included to give you an idea of how you could process the response if you API would return data when you perform a DELETE request.

communicate with our REST API back-end.

stores all data in memory:

Our new method implementations look a lot simpler because the data logic is now handled by the REST API.

However, there is an important difference. The old methods contained synchronous code and immediately returned a value. The updated methods contain asynchronous code and return an Observable.

methods to handle Observables correctly.

to directly return JavaScript objects and arrays:

methods return Observables.

Similar to Promises, Observables are asynchronous in nature, so we have to update the code to handle the Observable responses accordingly:

method:

which, in turn, instructs the Angular HTTP service to perform an HTTP GET request:

However, there is one important thing we have to remember!

As long as we don’t subscribe to the Observable returned by:

no actual HTTP request is made.

method, which takes 3 arguments:

Let’s rewrite our current code:

is initialized:

and set its initial value to an empty array.

, overwriting its initial value of an empty array.

method to also handle an Observable response:

and when the response comes in, we add the newly created todo to the current list of todo’s.

looks like this:

methods.

Let’s see if everything is working as expected.

Open a terminal window.

From the root of our application directory, start the REST API back-end:

Open a second terminal window.

Again, from the root of our application directory, serve the Angular application:

If all goes well, you should see:

If you see an error, you can compare your code to the working version on GitHub.

Awesome! Our application is now communicating with the REST API!

Let’s run our unit tests to verify that everything is working as expected.

Running our tests

Open a third terminal window.

Again, from the root of your application directory, run the unit tests:

It seems that 11 unit tests are failing:

Let’s see why our tests are failing and how we can fix them.

, so let’s remove the obsolete tests:

If we now run the unit tests, we get an error:

, which connects to our REST API.

in unit tests.

which shows:

, but we let the methods return mock data instead of making HTTP requests:

Notice how each method returns fresh new mock data. This may seem a bit repetitive, but is a good practice. If one unit test would change mock data, the change can never affect the data in another unit test.

again.

is requested:

If we now re-run the unit tests, the error is gone. Great!

We still have 2 more failing tests though:

The errors are similar to the one we just fixed.

Don’t worry if configuring the test module looks a bit overwhelming.

You can learn more about setting up unit test in the official documentation for testing Angular applications.

To fix the final error:

Hurray! All our tests are passing:

We have successfully connected our Angular application to our REST API back-end.

To deploy our application to a production environment, we can now run:

directory to our hosting server. How sweet is that?

Let’s recap what we have learned.

In the first article, we learned how to:

to delegate most of its work to:

In this third article, we:

In the process, we learned:

All code from this article is available at https://github.com/sitepoint-editors/angular-todo-app/tree/part-3.

to use the router to fetch the todo’s from the back-end.

In part five, we will implement authentication to prevent unauthorized access to our application.

So stay tuned for more!

This article was peer reviewed by Vildan Softic. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!

Angular and RxJS: Create an API Service to Talk to a REST Backend — SitePoint

You might also like More from author

Comments are closed, but trackbacks and pingbacks are open.