Angular 9/8 with PHP: Consuming a RESTful CRUD API with HttpClient and Forms

Angular 9/8 with PHP: Consuming a RESTful CRUD API with HttpClient and Forms

In the previous tutorial, you have implemented the PHP and MySQL backend that exposes a REST API for working with an insurance database. Let's now create the Angular 9 backend.

Connecting with a PHP Backend with Angular 9 HttpClient

In this tutorial, you'll learn how to use HttpClient in Angular 9 to make HTTP calls to a REST API and use template-based forms to submit data.

Now that you've created the RESTful API with a PHP script, you can proceed to create your Angular 9 project.

Installing Angular CLI 9

The recommended way of creating Angular projects is through using Angular CLI, the official tool created by the Angular team. The latest and best version yet is Angular CLI 9 so head back to another terminal window and run the following command to install the CLI:

$ npm install -g @angular/cli

Note: This will install Angular CLI 9 globally so make sure you have configured npm to install packages globally without adding sudo in Debian systems and macOS or using an administrator command prompt on Windows. You can also just fix your npm permissions if you get any issues

Generating a Angular 9 New Project

That's it! You can now use the CLI to create an Angular 9 project using the following command:

$ cd angular-9-php-app
$ ng new frontend

The CLI will ask you if Would you like to add Angular routing? type y because we'll need routing setup in our application. And Which stylesheet format would you like to use? Select CSS.

Wait for the CLI to generate and install the required dependencies and then you can start your development server using:

$ cd frontend
$ ng serve

You can access the frontend application by pointing your browser to the http://localhost:4200 address.

Setting up Angular HttpClient & Forms

Angular provides developers with a powerful HTTP client for sending requests to servers. It's based on the XMLHttpRequest interface supported on most browsers and has a plethora of features like the use of RxJS Observable instead of callbacks or promises, typed requests and responses and interceptors.

You can setup HttpClient in your project by simply importing the HttpClientModule in your main application module.

We'll also be using a template-based form in our application so we need to import FormsModule.

Open the src/app/app.module.ts file and import HttpClientModule then ad it to the imports array of @NgModule:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule } from  '@angular/forms';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    FormsModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

That's it! You can now use HttpClient in your components or services via dependency injection.

Creating an Angular 9 Service

Let's now, create an Angular 9 service that will encapsulate all the code needed for interfacing with the RESTful PHP backend.

Open a new terminal window, navigate to your frontend project and run the following command:

$ ng generate service api

This will create the src/app/api.service.spec.ts and src/app/api.service.ts files with a minimal required code.

Open the src/app/api.service.ts and start by importing and injecting HttpClient:

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

@Injectable({
  providedIn: 'root'
})
export class ApiService {

  constructor(private httpClient: HttpClient) {}
}

We inject HttpClient as a private httpClient instance via the service constructor. This is called dependency injection. If you are not familiar with this pattern. Here is the definition from Wikipedia:

In software engineering, dependency injection is a technique whereby one object (or static method) supplies the dependencies of another object. A dependency is an object that can be used (a service). An injection is the passing of a dependency to a dependent object (a client) that would use it. The service is made part of the client's state.[1] Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern.

Also this is what Angular docs says about dependency injection in Angular:

Dependency injection (DI), is an important application design pattern. Angular has its own DI framework, which is typically used in the design of Angular applications to increase their efficiency and modularity. Dependencies are services or objects that a class needs to perform its function. DI is a coding pattern in which a class asks for dependencies from external sources rather than creating them itself.

You can now use the injected httpClient instance to send HTTP requests to your PHP REST API.

Creating the Policy Model

Create a policy.ts file in the src/app folder of your project and the add the following TypeScript class:

export  class  Policy {
    id: number;
    number:  number;
    amount:  number;
}

Defining the CRUD Methods

Next, open the src/app/api.service.ts file and import the Policy model and the RxJS Observable interface:

import { Policy } from  './policy';
import { Observable } from  'rxjs';

Next, define the PHP_API_SERVER variable in the service:

export class ApiService {
  PHP_API_SERVER = "http://127.0.0.1:8080";

The PHP_API_SERVER holds the address of the PHP server.

Next, add the readPolicies() method that will be used to retrieve the insurance policies from the REST API endpoint via a GET request:

  readPolicies(): Observable<Policy[]>{
    return this.httpClient.get<Policy[]>(`${this.PHP_API_SERVER}/api/read.php`);
  }

Next, add the createPolicy() method that will be used to crate a policy in the database:

  createPolicy(policy: Policy): Observable<Policy>{
    return this.httpClient.post<Policy>(`${this.PHP_API_SERVER}/api/create.php`, policy);
  }

Next, add the updatePolicy() method to update policies:

  updatePolicy(policy: Policy){
    return this.httpClient.put<Policy>(`${this.PHP_API_SERVER}/api/update.php`, policy);   
  }

Finally, add the deletePolicy() to delete policies from the SQL database:

  deletePolicy(id: number){
    return this.httpClient.delete<Policy>(`${this.PHP_API_SERVER}/api/delete.php/?id=${id}`);
  }

That's all for the service.

Creating the Angular 9 Component

After creating the service that contains the CRUD operations, let's now create an Angular 9 component that will call the service methods and wil contain the table to display policies and a form to submit a policy to the PHP backend.

head back to your terminal and run the following command:

$ ng generate component dashboard

Let's add this component to the Router. Open the src/app/app-routing.module.ts file and add a /dashboard route:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DashboardComponent } from './dashboard/dashboard.component';


const routes: Routes = [
  { path: 'dashboard', component: DashboardComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

You can now access your dashboard component from the 127.0.0.1:4200/dashboard URL. This is a screenshot of the page at this point:

PHP Angular REST CRUD example

Let's remove the boilerplate content added by Angular CLI. Open the src/app/app.component.html file and update accordingly:

<router-outlet></router-outlet>

We only leave the router outlet where Angular router will insert the matched component(s).

Next, open the src/app/dashboard/dashboard.component.ts file and import ApiService then inject it via the component constructor:

import { Component, OnInit } from '@angular/core';
import { ApiService } from '../api.service';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {

  constructor(private apiService: ApiService) { }

  ngOnInit() {
  }
}

We inject ApiService as a private apiService instance.

Next, let's define the policies array that will hold the insurance policies once we get them from the server after we send a GET request and also the selectedPolicy variable that will hold the selected policy from the table.

export  class  DashboardComponent  implements  OnInit {
    policies:  Policy[];
    selectedPolicy:  Policy  = { id :  null , number:null, amount:  null};

On the ngOnInit() method of the component, let's call the readPolicies() method of ApiService to get the policies:

  ngOnInit() {
    this.apiService.readPolicies().subscribe((policies: Policy[])=>{
      this.policies = policies;
      console.log(this.policies);
    })
  }

We call the readPolicies() which return an Observable<Policy[]> object and we subscribe to the RxJS Observable. We then assign the returned policies to the policies array of our component and we also log the result in the console.

Note: The actual HTTP request is only sent to the server when you subscribe to the returned Observable.

You should see the returned policies in your browser console. This is a screenshot of the output in my case:

Angular PHP example

We'll see a bit later how to display these policies in a table in the component template.

Let's add the other methods to create, update and delete policies in our component.

  createOrUpdatePolicy(form){
    if(this.selectedPolicy && this.selectedPolicy.id){
      form.value.id = this.selectedPolicy.id;
      this.apiService.updatePolicy(form.value).subscribe((policy: Policy)=>{
        console.log("Policy updated" , policy);
      });
    }
    else{

      this.apiService.createPolicy(form.value).subscribe((policy: Policy)=>{
        console.log("Policy created, ", policy);
      });
    }

  }

  selectPolicy(policy: Policy){
    this.selectedPolicy = policy;
  }

  deletePolicy(id){
    this.apiService.deletePolicy(id).subscribe((policy: Policy)=>{
      console.log("Policy deleted, ", policy);
    });
  }

Adding the Table and Form

Let's now add a table and form to display and create the policies in our dashboard component. Open the src/app/dashboard/dashboard.component.html and add the following HTML code:

<h1>Insurance Policy Management</h1>
<div>

  <table border='1' width='100%' style='border-collapse: collapse;'>
    <tr>
      <th>ID</th>
      <th>Policy Number</th>
      <th>Policy Amount</th>
      <th>Operations</th>

    </tr>

    <tr *ngFor="let policy of policies">
      <td>{{ policy.id }}</td>
      <td>{{ policy.number }}</td>
      <td>{{ policy.amount }}</td>
      <td>
        <button (click)="deletePolicy(policy.id)">Delete</button>
        <button (click)="selectPolicy(policy)">Update</button>
      </td>
    </tr>
  </table>

This is a screenshot of the page at this point:

PHP Angular Example

Next, below the table, let's add a form that will be used to create and update a policy:

<br>
  <form #f = "ngForm">
    <label>Number</label>
    <input type="text" name="number" [(ngModel)] = "selectedPolicy.number">
    <br>
    <label>Amount</label>
    <input type="text" name="amount" [(ngModel)] = "selectedPolicy.amount">
    <br>
    <input type="button" (click)="createOrUpdatePolicy(f)" value="Create or Update Policy">
  </form>

This is a screenshot of the page at this point:

Angular PHP CRUD Example

Next, open the src/app/dashboard/dashboard.component.css file and the following CSS styles:

input {
    width: 100%;
    padding: 2px 5px;
    margin: 2px 0;
    border: 1px solid red;
    border-radius: 4px;
    box-sizing: border-box;
  }

  button, input[type=button]{
    background-color: #4CAF50;
    border: none;
    color: white;
    padding: 4px 7px;
    text-decoration: none;
    margin: 2px 1px;
    cursor: pointer;
  }
  th, td {
    padding: 1px;
    text-align: left;
    border-bottom: 1px solid #ddd;

  }
  tr:hover {background-color: #f5f5f5;}

This is a screenshot of the page after adding some minimal styling:

PHP Angular REST CRUD Example

Conclusion

In this tutorial, we learned how to create a RESTful CRUD application with PHP, MySQL and Angular 9.



Angular 9 Components: Input and Output
Angular 13 selectors
Picture-in-Picture with JavaScript and Angular 10
Jasmine Unit Testing for Angular 12
Angular 9 Tutorial By Example: REST CRUD APIs & HTTP GET Requests with HttpClient
Angular 10/9 Elements Tutorial by Example: Building Web Components
Angular 10/9 Router Tutorial: Learn Routing & Navigation by Example
Angular 10/9 Router CanActivate Guards and UrlTree Parsed Routes
Angular 10/9 JWT Authentication Tutorial with Example
Style Angular 10/9 Components with CSS and ngStyle/ngClass Directives
Upload Images In TypeScript/Node & Angular 9/Ionic 5: Working with Imports, Decorators, Async/Await and FormData
Angular 9/Ionic 5 Chat App: Unsubscribe from RxJS Subjects, OnDestroy/OnInit and ChangeDetectorRef
Adding UI Guards, Auto-Scrolling, Auth State, Typing Indicators and File Attachments with FileReader to your Angular 9/Ionic 5 Chat App
Private Chat Rooms in Angular 9/Ionic 5: Working with TypeScript Strings, Arrays, Promises, and RxJS Behavior/Replay Subjects
Building a Chat App with TypeScript/Node.js, Ionic 5/Angular 9 & PubNub/Chatkit
Chat Read Cursors with Angular 9/Ionic 5 Chat App: Working with TypeScript Variables/Methods & Textarea Keydown/Focusin Events
Add JWT REST API Authentication to Your Node.js/TypeScript Backend with TypeORM and SQLite3 Database
Building Chat App Frontend UI with JWT Auth Using Ionic 5/Angular 9
Install Angular 10 CLI with NPM and Create a New Example App with Routing
Styling An Angular 10 Example App with Bootstrap 4 Navbar, Jumbotron, Tables, Forms and Cards
Integrate Bootstrap 4/jQuery with Angular 10 and Styling the UI With Navbar and Table CSS Classes
Angular 10/9 Tutorial and Example: Build your First Angular App
Angular 9/8 ngIf Tutorial & Example
Angular 10 New Features
Create New Angular 9 Workspace and Application: Using Build and Serve
Angular 10 Release Date: Angular 10 Will Focus on Ivy Artifacts and Libraries Support
HTML5 Download Attribute with TypeScript and Angular 9
Angular 9.1+ Local Direction Query API: getLocaleDirection Example
Angular 9.1 displayBlock CLI Component Generator Option by Example
Angular 9 Basics Tutorial by Example
Angular 9/8 ngFor Directive: Render Arrays with ngFor by Example
Responsive Image Breakpoints Example with CDK's BreakpointObserver in Angular 9/8
Angular 9/8 DOM Queries: ViewChild and ViewChildren Example
The Angular 9/8 Router: Route Parameters with Snapshot and ParamMap by Example
Angular 9/8 Nested Routing and Child Routes by Example
Angular 9 Examples: 2 Ways To Display A Component (Selector & Router)
Angular 9/8 Tutorial: Http POST to Node/Express.js Example
Angular 9/8 Feature and Root Modules by Example
Angular 9/8 with PHP: Consuming a RESTful CRUD API with HttpClient and Forms
Angular 9/8 with PHP and MySQL Database: REST CRUD Example & Tutorial
Unit Testing Angular 9/8 Apps Tutorial with Jasmine & Karma by Example
Angular 9 Web Components: Custom Elements & Shadow DOM
Angular 9 Renderer2 with Directives Tutorial by Example
Build Progressive Web Apps (PWA) with Angular 9/8 Tutorial and Example
Angular 9 Internationalization/Localization with ngx-translate Tutorial and Example
Create Angular 9 Calendar with ngx-bootstrap datepicker Example and Tutorial
Multiple File Upload with Angular 9 FormData and PHP by Example
Angular 9/8 Reactive Forms with Validation Tutorial by Example
Angular 9/8 Template Forms Tutorial: Example Authentication Form (ngModel/ngForm/ngSubmit)
Angular 9/8 JAMStack By Example
Angular HttpClient v9/8 — Building a Service for Sending API Calls and Fetching Data
Build an Angular 9/8 CRUD Example & Tutorial
Styling An Angular 9/8/7 Example App with Bootstrap 4 Navbar, Jumbotron, Tables, Forms and Cards
Angular 8/7 Tutorial By Example: (REST API, HttpClient GET, Components, Services & ngFor)

✋If you have any questions about this article, ask them in our GitHub Discussions 👈 community. You can also Gitter

✋ Want to master Angular 14? Read our angular tutorial and join our #DailyAngularChallenge where we learn to build components, directives, services, pipes and complete web, mobile, and desktop applications with latest Angular version.

✋ Make sure to join our Angular 14 Dev Community 👈 to discuss anything related to Angular development.

❤️ Like our page and subscribe to our feed for updates!