Angular 17 CRUD Tutorial: Consume a CRUD REST API

Angular 17 CRUD Tutorial: Consume a CRUD REST API

This guide is designed for developers who want to use Angular 17 to create front-end apps for their back-end REST APIs. If you don't want to deal with Python, you may simulate the API using JSON-Server, or you can use Python and Django as the backend. Both techniques will be shown in this post.

Check out the rest of this tutorial:

If you would like to consume a third-party REST API rather than developing your own API, make sure to check out this tutorial.

You will learn by practicing how to create a CRUD REST API in Python.

Throughout this beginner-level tutorial, you'll learn Angular by practicing by making a complete CRUD — Create, Read, Update, and Delete — web application with the most recent version of the most popular framework and platform for building mobile and desktop client side applications (also known as SPAs or Single Page Applications) created and used internally by Google.

In the backend, we'll be using Python with Django, the most popular pythonic web framework designed for perfectionists with tight schedules.

In the back-end we'll use Python with Django, the most popular pythonic web framework designed for perfectionists with deadlines.

In a nutshell, you'll master how to create applications, components, and services, as well as how to implement routing.

You'll also understand how to utilize features like HttpClient for making AJAX requests and HTTP calls, as well as subscribe to RxJS Observables.

You'll learn through developing a real-world sample application by the completion of this tutorial:

  • How to install the latest version of the CLI,
  • How to use the CLI to generate a new Angular 17 project,
  • How to build a simple CRM application,
  • What's a component and component-based architecture
  • How to use RxJS Observables and operators (map() and filter() etc.)
  • How to create components,
  • How to add component routing and navigation,
  • How to use HttpClient to consume a REST API etc.

Prerequisites

You will need to have the following prerequisites in order to follow this tutorial:

  • A Python development environment. We use a Ubuntu system with Python 3.7 and pip installed but you can follow these instructions in a different system as long as you have Python 3 and pip installed. Also the commands shown here are bash commands which are available in Linux-based systems and macOS but if you use Windows CMD or Powershell , make sure to use the equivalent commands or install bash for Windows.
  • Node.js and npm installed on your system. They are required by Angular CLI.
  • Familiarity with TypeScript.

You are ready to begin if you meet these prerequisites!

Starting the Python REST API Server

We'll be using a Python REST API that we have created in this tutorial. Go ahead and clone the project's code from GitHub using the following command:

$ git clone https://github.com/techiediaries/python-django-crm-rest-api.git 

Next, create and activate a virtual environment as follows:

$ python3 -m venv .env
$ source .env/bin/activate

Next, navigate to your CRM project and install the requirements using pip:

$ cd python-django-crm-rest-api
$ pip install -r requirements.txt

Finally, you can run the development server using the following command:

$ python manage.py runserver

Your REST API will be available from the http://localhost:8000/ address with CORS enabled.

Mocking the Same REST API with json-server

If you don't want to use a real Python & Django REST API server, you can also use json-server to quickly mock the REST API.

First, let's install json-server in our system using the following command:

$ npm install -g json-server

Next, create a folder for your server and create a JSON file (data.json) with the following content:

{
    "users":[
        {
            "id": 1,
            "first_name": "Robert",
            "last_name": "Schwartz",
            "email": "[email protected]"
        }

    ],
    "accounts": [
        {
            "id": 1,
            "name": "",
            "email":"",
            "phone": "",
            "industry": "",
            "website": "",
            "description": "",
            "createdBy": 1,
            "createdAt": "",
            "isActive": true
        }
    ],
    "contacts": [
        {
            "id": 1,
            "first_name": "",
            "last_name": "",
            "account": 1,
            "status":1,
            "source": 1,
            "email": "",
            "phone": "",
            "address": "",
            "description": "",
            "createdBy": 1,
            "createdAt": "",
            "isActive": true
        }
    ],
    "activities": [
        {
            "id": 1,
            "description": "",
            "createdAt" : "",
            "contact": 1,
            "status": 1
        }
    ],
    "contactsources": [
        {
            "id":1,
            "source": ""
        }
    ],
    "contactstatuses": [
        {
            "id":1,
            "status": ""
        }
    ],
    "activitystatuses":[
        {
            "id":1,
            "status": ""
        }
    ]
}

We added empty entries for JSON data. Feel free to add your own data or use a tool like Faker.js to automatically generate fake data.

Next, you need to start the JSON server using the following command:

$ json-server --watch data.json  

Your REST API server will be running at http://localhost:3000.

We'll have the following resources exposed:

  • http://localhost:3000/users
  • http://localhost:3000/accounts
  • http://localhost:3000/contacts
  • http://localhost:3000/activities
  • http://localhost:3000/contactsources
  • http://localhost:3000/contactstatuses
  • http://localhost:3000/activitystatuses

This is almost identical to the REST API served by our actual Python REST API server.

The angular 17 application we'll develop as an illustration is the front-end for the CRM RESTful API, which allows you to create accounts, contacts, and activities. It's a great example of a CRUD (Create, Read, Update, and Delete) SPA application (Single Page Application). The sample application is still under development, so we'll be developing it over a series of tutorials and updating it to include advanced features like RxJS and JWT authentication.

Installing the Angular CLI 17

Make sure you have Node.js installed before using the command below in your terminal to install Angular CLI 17:

$ npm install @angular/cli@beta --global

At the time of this writing @angular/cli v17 beta will be installed.

You can verify the installed version by running the following command:

$ ng version

You are now ready to start working on a project using Angular CLI 17. Simply type the following into your terminal:

ng new ngsimplecrm

The CLI will create a number of files that are typical to most Angular 17 applications and install the necessary dependencies for your project.

The CLI will prompt you if Would you like to add Angular routing? (y/N), type y. And Which stylesheet format would you like to use? Choose CSS and type Enter.

Next, you can serve your application locally using the following commands:

$ cd ./ngsimplecrm
$ ng serve

The command will compile your project and finally will serve your application from http://localhost:4200.

What's a Component

A component is a TypeScript class that controls a region of the screen using an HTML template and an optional set of CSS styling.

The most fundamental aspect in Angular is components. An Angular application is essentially a component tree with a root component (the well-known AppComponent). The root component is the one declared in the bootstrap array of the main NgModule module in the app.module.ts file.

Reusability is a fundamental property of components. A component may be reused inside the application and even in other apps. Common and repetitive code that accomplishes a certain activity may be wrapped into a reusable component and invoked anytime the function it offers is required.

Each bootstrapped component is the base of its own tree of components. Inserting a bootstrapped component usually triggers a cascade of component creations that fill out that tree. source

What's a Component-Based Architecture?

An Angular application is made up of many components that create a tree architecture with parent and child components.

A component is a self-contained unit of a larger system (web application) that connects with the system's other building blocks (components) through inputs and outputs. A component has a view, data, and behavior connected with it, and it may have parent and child components.

Components provide optimum reusability, simple testing, maintenance, and concern separation.

Let's now see this practically. Head over to your Angular project folder and open the src/app folder. You will find the following files:

  • app.component.css: the CSS file for the component
  • app.component.html: the HTML view for the component
  • app.component.spec.ts: the unit tests or spec file for the component
  • app.component.ts: the component code (data and behavior)
  • app.module.ts: the application main module

Except for the last file which contains the declaration of the application main (root) Module, all these files are used to create a component. It's the AppComponent: The root component of our application. All other components we are going to create next will be direct or un-direct children of the root component.

Demystifying the App Component

Go ahead and open the src/app/app.component.ts file and let's understand the code behind the root component of the application.

First, this is the code:

import { Component } from  '@angular/core';
@Component({
    selector:  'app-root',
    templateUrl:  './app.component.html',
    styleUrls: ['./app.component.css']
})
export  class  AppComponent {
    title  =  'app';
}

We first import the Component decorator from @angular/core then we use it to decorate the TypeScript class AppComponent. The Component decorator takes an object with many parameters such as:

  • selector: specifies the tag that can be used to call this component in HTML templates just like the standard HTML tags
  • templateUrl: indicates the path of the HTML template that will be used to display this component (you can also use the template parameter to include the template inline as a string)
  • styleUrls: specifies an array of URLs for CSS style-sheets for the component

The export keyword is used to export the component so that it can be imported from other components and modules in the application.

The title variable is a member variable that holds the string 'app'. There is nothing special about this variable and it's not a part of the canonical definition of an Angular component.

Now let's see the corresponding template for this component. If you open src/app/app.component.html this is what you'll find:

<div  style="text-align:center">
<h1>
Welcome to !
</h1>
    <img  width="300"  alt="Angular Logo"  src="data:image/svg+xml;....">
</div>

    <h2>Here are some links to help you start: </h2>
<ul>
    <li>
    <h2><a  target="_blank"  rel="noopener"  href="https://angular.io/tutorial">Tour of Heroes</a></h2>
    </li>
    <li>
    <h2><a  target="_blank"  rel="noopener"  href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
    </li>
    <li>
    <h2><a  target="_blank"  rel="noopener"  href="https://blog.angular.io/">Angular blog</a></h2>
    </li>
</ul>

The template is a normal HTML file (almost all HTML tags are valid to be used inside Angular templates except for some tags such as <script>, <html> and <body>) with the exception that it can contain template variables (in this case the title variable) or expressions (``) that can be used to insert values in the DOM dynamically. This is called interpolation or data binding. You can find more information about templates from the docs.

You can also use other components directly inside Angular templates (via the selector property) just like normal HTML.

Note: If you are familiar with the MVC (Model View Controller) pattern, the component class plays the role of the Controller and the HTML template plays the role of the View.

Components by Example

After getting the theory behind Angular components, let's now create the components for our simple CRM application.

Our REST API, built either with Django or JSON-Server, exposes these endpoints:

  • /accounts: create or read a paginated list of accounts
  • /accounts/<id>: read, update or delete an account

  • /contacts: create or read a paginated list of contacts

  • /contacts/<id>: read, update or delete a contact

  • /activities: create or read a paginated list of activities

  • /activities/<id>: read, update or delete an activity

  • /contactstatuses: create or read a paginated list of contact statuses

  • /activitystatuses: create or read a paginated list of activity statuses

  • /contactsources: create or read a paginated list of contact sources

Before adding routing to our application, we first need to create the application components - so based on the exposed REST API architecture we can initially divide our application into these components:

  • AccountListComponent: this component displays and controls a tabular list of accounts
  • AccountCreateComponent: this component displays and controls a form for creating or updating accounts

  • ContactListComponent: displays a table of contacts

  • ContactCreateComponent: displays a form to create or update a contact

  • ActivityListComponent: displays a table of activities

  • ActivityCreateComponent: displays a form to create or update an activity

Let's use the Angular CLI to create the components. Open a new terminal and run the following commands:

$ ng generate component AccountList
$ ng generate component AccountCreate

$ ng generate component ContactList
$ ng generate component ContactCreate

$ ng generate component ActivityList
$ ng generate component ActivityCreate

This is the output of the first command:

CREATE src/app/account-list/account-list.component.css (0 bytes)
CREATE src/app/account-list/account-list.component.html (31 bytes)
CREATE src/app/account-list/account-list.component.spec.ts (664 bytes)
CREATE src/app/account-list/account-list.component.ts (292 bytes)
UPDATE src/app/app.module.ts (418 bytes)

You can see that the command generates all the files to define a component and also updates src/app/app.module.ts to include the component.

If you open src/app/app.module.ts after running all commands, you can see that all components are automatically added to the AppModule declarations array:

import { BrowserModule } from  '@angular/platform-browser';
import { NgModule } from  '@angular/core';



import { AppComponent } from  './app.component';
import { AccountListComponent } from  './account-list/account-list.component';
import { AccountCreateComponent } from  './account-create/account-create.component';
import { ContactListComponent } from  './contact-list/contact-list.component';
import { ContactCreateComponent } from  './contact-create/contact-create.component';


@NgModule({

declarations: [
    AppComponent,
    AccountListComponent,
    AccountCreateComponent,
    ContactListComponent,
    ContactCreateComponent,
    ActivityListComponent,
    ActivityCreateComponent 
],
imports: [
    BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export  class  AppModule { }

Note: If you are creating components manually, you need to make sure to include them manually so they can be recognized as part of the module.

Setting up HttpClient

Now that we've created the various components, let's set up HttpClient in our Angular 17 project to consume the RESTful API back-end.

You simply need to add HttpClientModule to the imports array of the main application module:

// [...]
import { HttpClientModule } from  '@angular/common/http';

@NgModule({

declarations: [
// [...]
],

imports: [

// [...]

HttpClientModule
],
providers: [],
bootstrap: [AppComponent]

})

export  class  AppModule { }

We can now use HttpClient in our application.

Create Services

A service is a global class that can be injected in any component. It's used to encapsulate code that can be common between multiple components in one place instead of repeating it throughout various components.

Now, let's create the services that encapsulates all the code needed for interacting with the REST API. Using Angular CLI 8 run the following commands:

$ ng generate service services/contact
$ ng generate service services/activity
$ ng generate service services/account

Note: Since we have multiple services, we can put them in a services folder or whatever you want to call it.

Injecting HttpClient in the Services

Open the src/app/services/contact.service.ts file then import and inject HttpClient:

import { Injectable } from  '@angular/core';
import { HttpClient } from  '@angular/common/http';

@Injectable({
providedIn:  'root'
})

export  class  ContactService {

    constructor(private  httpClient:  HttpClient) {}

}

Note: You will need to do the same for the other services.

Angular provides a way to register services/providers directly in the @Injectable() decorator by using the new providedIn attribute. This attribute accepts any module of your application or 'root' for the main app module. Now you don't have to include your service in the providers array of your module.

Conclusion

Through the creation of a straightforward real-world CRUD example, we have learnt how to mix several Angular 17 capabilities to create a fundamental full-stack CRUD application.

This post is written for developers who want to use Angular 17 to construct front-end apps for their back-end REST APIs. If you don't want to deal with Python, you may imitate the API using JSON-Server. The backend can be developed in Python and Django. This lesson demonstrated both of these techniques.

In the next tutorial we'll be learning how to add routing to our example application.


  • Date: