Django + Angular 6 example | Django Rest Framework + MySQL CRUD example – Part 3: Angular Client

django-angular-6-django-rest-api-mysql-angular-django-project-structure-feature-image

This tutorial is part 3 of Django-Angular-MySQL series. Today, we will create Angular Client to make HTTP request & receive response from Django Server.

>> Part 1: Overview
>> Part 2: Django Server

Video

Angular Client Overview

Goal

The image below shows overview about Angular Components that we will create:

django-angular-6-django-rest-api-mysql-angular-client-architecture

Project Structure

django-angular-6-django-rest-api-mysql-angular-project-structure

We have:
– 4 components: customers-list, customer-details, create-customer, search-customer.
– 3 modules: FormsModule, HttpClientModule, AppRoutingModule.
customer.ts: class Customer (id, firstName, lastName)
customer.service.ts: Service for Http Client methods
app-routing.module.ts: Routing configuration

Setup Angular Project

Create Angular Project

Run command: ng new AngularDjango.

Create Service & Components

On Project folder, run commands below:
ng g s customer
ng g c create-customer
ng g c customer-details
ng g c customers-list
ng g c search-customers
On each Component selector, delete app- prefix, then change tslint.json rules"component-selector" to false.

Implement Angular Client App

Data Model

Create new file named customer.ts:

export class Customer {
    id: number;
    name: string;
    age: number;
    active: boolean;
}

Data Service

customer.service.ts

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

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

  private baseUrl = 'http://localhost:8000/customers';

  constructor(private http: HttpClient) { }

  getCustomer(id: number): Observable<object width="300" height="150"> {
    return this.http.get(`${this.baseUrl}/${id}`);
  }

  createCustomer(customer: Object): Observable<object> {
    return this.http.post(`${this.baseUrl}/`, customer);
  }

  updateCustomer(id: number, value: any): Observable<object> {
    return this.http.put(`${this.baseUrl}/${id}`, value);
  }

  deleteCustomer(id: number): Observable<any> {
    return this.http.delete(`${this.baseUrl}/${id}`);
  }

  getCustomersList(): Observable<any> {
    return this.http.get(`${this.baseUrl}/`);
  }

  getCustomersByAge(age: number): Observable<any> {
    return this.http.get(`${this.baseUrl}/age/${age}/`);
  }

  deleteAll(): Observable<any> {
    return this.http.delete(`${this.baseUrl}/`);
  }
}

Components

Customer Details

customer-details/customer-details.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { CustomerService } from '../customer.service';
import { Customer } from '../customer';

import { CustomersListComponent } from '../customers-list/customers-list.component';

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

  @Input() customer: Customer;

  constructor(private customerService: CustomerService, private listComponent: CustomersListComponent) { }

  ngOnInit() {
  }

  updateActive(isActive: boolean) {
    this.customerService.updateCustomer(this.customer.id,
      { name: this.customer.name, age: this.customer.age, active: isActive })
      .subscribe(
        data => {
          console.log(data);
          this.customer = data as Customer;
        },
        error => console.log(error));
  }

  deleteCustomer() {
    this.customerService.deleteCustomer(this.customer.id)
      .subscribe(
        data => {
          console.log(data);
          this.listComponent.reloadData();
        },
        error => console.log(error));
  }

}

customer-details/customer-details.component.html

<div *ngIf="customer">
  <div>
    <label>Name: </label> {{customer.name}}
  </div>
  <div>
    <label>Age: </label> {{customer.age}}
  </div>
  <div>
    <label>Active: </label> {{customer.active}}
  </div>

  <span class="button is-small btn-primary" *ngIf='customer.active' (click)='updateActive(false)'>Inactive</span>

  <span class="button is-small btn-primary" *ngIf='!customer.active' (click)='updateActive(true)'>Active</span>

  <span class="button is-small btn-danger" (click)='deleteCustomer()'>Delete</span>

  <hr />
</div>

List of Customers

customers-list/customers-list.component.ts

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';

import { CustomerService } from '../customer.service';
import { Customer } from '../customer';

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

  customers: Observable;

  constructor(private customerService: CustomerService) { }

  ngOnInit() {
    this.reloadData();
  }

  deleteCustomers() {
    this.customerService.deleteAll()
      .subscribe(
        data => {
          console.log(data);
          this.reloadData();
        },
        error => console.log('ERROR: ' + error));
  }

  reloadData() {
    this.customers = this.customerService.getCustomersList();
  }

}

customers-list/customers-list.component.html

<h1>Customers</h1>

<div *ngFor="let customer of customers | async" style="width: 300px;">
  <customer-details [customer]='customer'></customer-details>
</div>

<div>
  <button type="button" class="button btn-danger" (click)='deleteCustomers()'>Delete All</button>
</div>

Create Customer

create-customer/create-customer.component.ts

import { Component, OnInit } from '@angular/core';

import { Customer } from '../customer';
import { CustomerService } from '../customer.service';

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

  customer: Customer = new Customer();
  submitted = false;

  constructor(private customerService: CustomerService) { }

  ngOnInit() {
  }

  newCustomer(): void {
    this.submitted = false;
    this.customer = new Customer();
  }

  save() {
    this.customerService.createCustomer(this.customer)
      .subscribe(
        data => {
          console.log(data);
          this.submitted = true;
        },
        error => console.log(error));
    this.customer = new Customer();
  }

  onSubmit() {
    this.save();
  }

}

create-customer/create-customer.component.html

<h3>Create Customer</h3>
<div [hidden]="submitted" style="width: 300px;">
  <form (ngSubmit)="onSubmit()">
    <div class="form-group">
      <label for="name">Name</label>
      <input type="text" class="form-control" id="name" required [(ngModel)]="customer.name" name="name">
    </div>

    <div class="form-group">
      <label for="age">Age</label>
      <input type="text" class="form-control" id="age" required [(ngModel)]="customer.age" name="age">
    </div>

    <button type="submit" class="btn btn-success">Submit</button>
  </form>
</div>

<div [hidden]="!submitted">
  <h4>You submitted successfully!</h4>
  <button class="btn btn-success" (click)="newCustomer()">Add</button>
</div>

Search Customers

search-customers/search-customers.component.ts

import { Component, OnInit } from '@angular/core';
import { Customer } from '../customer';
import { CustomerService } from '../customer.service';

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

  age: number;
  customers: Customer[];

  constructor(private dataService: CustomerService) { }

  ngOnInit() {
    this.age = 0;
  }

  private searchCustomers() {
    this.customers = [];
    this.dataService.getCustomersByAge(this.age)
      .subscribe(customers => this.customers = customers);
  }

  onSubmit() {
    this.searchCustomers();
  }

}

search-customers/search-customers.component.html

<h3>Find By Age</h3>
<div style="width: 300px;">
  
<div class="form-group">
      <label for="lastname">Age</label>
      <input type="text" class="form-control" id="age" required="" ngmodel="" age="" name="age">
</div>

<div class="btn-group">
      <button type="submit" class="btn btn-success">Submit</button>
</div>
  
</div>
<ul>
 	<li ngfor="let customer of customers">
<h4>{{customer.id}} - {{customer.name}} {{customer.age}}</h4>
</li>
</ul>
Add Router

app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CustomersListComponent } from './customers-list/customers-list.component';
import { CreateCustomerComponent } from './create-customer/create-customer.component';
import { SearchCustomersComponent } from './search-customers/search-customers.component';

const routes: Routes = [
    { path: '', redirectTo: 'customer', pathMatch: 'full' },
    { path: 'customer', component: CustomersListComponent },
    { path: 'add', component: CreateCustomerComponent },
    { path: 'findbyage', component: SearchCustomersComponent },
];

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

export class AppRoutingModule { }

And AppComponent HTML for routing:app.component.html

<div style="padding: 20px;">
<h1 style="color: blue;">ozenero.com</h1>
<h3>Angular - Django App</h3>
  <nav>
    <a routerlink="customer" class="btn btn-primary active" role="button" routerlinkactive="active">Customers</a>
    <a routerlink="add" class="btn btn-primary active" role="button" routerlinkactive="active">Add</a>
    <a routerlink="findbyage" class="btn btn-primary active" role="button" routerlinkactive="active">Search</a>
  </nav>
  <router-outlet></router-outlet>
</div>

App Module

app.module.ts

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

import { AppComponent } from './app.component';
import { CreateCustomerComponent } from './create-customer/create-customer.component';
import { CustomerDetailsComponent } from './customer-details/customer-details.component';
import { CustomersListComponent } from './customers-list/customers-list.component';
import { SearchCustomersComponent } from './search-customers/search-customers.component';

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

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

Run & Check Results

– Run Django server with command: python manage.py runserver.
– Run Angular App with command: ng serve.

– Open browser for url http://localhost:4200/:

Add Customer:

django-angular-6-example-django-rest-api-mysql-angular-add-customer

Show Customers:

django-angular-6-django-rest-api-mysql-angular-show-customers

Click on Active button to update Customer status:

django-angular-6-example-django-rest-api-mysql-angular-update-customers

Search Customers by Age:

django-angular-6-example-django-rest-api-mysql-angular-search-customers

Delete a Customer:

django-angular-6-example-django-rest-api-mysql-angular-delete-customer

Delete All Customers:

django-angular-6-example-django-rest-api-mysql-angular-delete-all-customers

Source Code

Angular-Django-MySQL-example-Angular-Rest-Client

0 0 votes
Article Rating
Subscribe
Notify of
guest
1.1K Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments