Angular 4 CRUD Example:

It would be great to checkout branch angular-crud-app from repository

Our objective is to be able to extend our bike app to :

  • be able to add, update and delete bikes.
  • be able to create bike on localhost:4200/bikes.
  • be able to delete bike from bikes list shown on localhost:4200/bikes.
  • be able to update bike information from bike-info page.

We need to implement angular 4 crud example as below.

  • update BikeService to write methods addBike()updateBike() and deleteBike().
  • update BikeInfoComponent to be able to navigate back and save bike details.
  • update BikesComponent to input a new bike and delete existing bikes.

Let’s get started with code.


import { Injectable } from '@angular/core';
import { Headers, Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import { Bike } from './bike'
export class BikeService {
  constructor(private http: Http) {
  private headers = new Headers({ 'Content-Type': 'application/json' });
  private bikesUrl = 'api/bikes';
  getBikes(): Promise<Bike[]> {
    return this.http.get(this.bikesUrl)
      .then(response => response.json().data as Bike[])
  getBike(id: number): Promise<Bike> {
    const url = `${this.bikesUrl}/${id}`;
    return this.http.get(url)
      .then(response => response.json().data as Bike)
  createBike(bike: Bike): Promise<Bike> {
    return this.http
      .post(this.bikesUrl, JSON.stringify(bike), { headers: this.headers })
      .then(res => res.json().data as Bike)
  updateBike(bike: Bike): Promise<Bike> {
    const url = `${this.bikesUrl}/${}`;
    return this.http
      .put(url, JSON.stringify(bike), { headers: this.headers })
      .then(() => bike)
  deleteBike(bike: Bike): Promise<void> {
    const url = `${this.bikesUrl}/${}`;
    return this.http.delete(url, { headers: this.headers })
      .then(() => null)
  private handleError(error: any): Promise<any> {
    console.error('An error occurred', error);
    return Promise.reject(error.message || error);
  • createBike(bike: Bike):  takes a bike object as parameter and makes a http POST request to ‘api/bikes‘ with data as new bike object. Created bike is returned as Promise.
  • updateBike(bike: Bike): takes a bike object as parameter and makes http PUT request to update bike details by id.
  • deleteBike(bike: Bike): takes bike object as parameter and makes http DELETE request to delete bike by id.


<div *ngIf="bike">
  <md-card style="width: 30%">
      <md-card-title>{{bike.model}} details!</md-card-title>
      <div><label>id: </label>{{}}</div>
        <label>model: </label>
        <input [(ngModel)]="bike.model" placeholder="model" />
        <label>Manufacturer: </label>
        <input [(ngModel)]="bike.manufacturer" placeholder="manufacturer" />
      <button md-button (click)="goBack()"> Back </button>
      <button md-button (click)="updateBike()"> Update </button>
  • Note that we are simply showing existing bike information and providing input boxes for it to update information.
  • We have added two actions. Back action simply navigates to previous page and Update action saves newly entered bike details.


import 'rxjs/add/operator/switchMap'
import { Component, OnInit, Input } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Location } from '@angular/common';

import { Bike } from '../bike';
import { BikeService } from '../bike.service'

  selector: 'app-bike-info',
  templateUrl: './bike-info.component.html',
  styleUrls: ['./bike-info.component.css']
export class BikeInfoComponent implements OnInit {

  bike: Bike;

    private bikeService: BikeService,
    private route: ActivatedRoute,
    private location: Location
  ) { }

  ngOnInit(): void {
    this.route.params.switchMap((params: Params) => this.bikeService.getBike(+params['id']))
      .subscribe(bike => = bike);
  updateBike(): void {
  goBack(): void {

  • we injected Location class so that we can use its methods.
  • updateBike(): simply calls updateBike(bike : Bike) from BikeService.
  • goBack(): simply navigates to previous page.

We modified BikeInfo component bike details. i.e. Work for update is done for angular 4 crud example. Let us see how to create and delete bikes.



  <md-input-container style="width:30%">
    <input mdInput [(ngModel)]="newBike.model" placeholder="Model" name="model">
  <md-input-container style="width:30%">
    <input mdInput [(ngModel)]="newBike.manufacturer" placeholder="Manufacturer" name="manufacturer">
  <button md-raised-button (click)="createBike(newBike)">Create Bike</button>

    <md-list-item *ngFor="let bike of bikes" (click)="showInfo(bike)">
        <button md-raised-button (click)="deleteBike(bike); $event.stopPropagation()">Delete</button>
  • This page has a form to create bike. Button calls createBike(newBike) method from bikes.component.ts.
  • Then it shows the list of all bikes. Delete button appears in front of each bike name. On click, it will call “deleteBike(bike)” from bikes.component.ts.  $event.stopPropagation() stops the app to navigate to bike details. This is because we are technically clicking on list item and it is supposed to navigate to bike info page.


import { Component, OnInit } from ‘@angular/core’;
import { Router } from ‘@angular/router’;
import { Bike } from ‘../bike’;
import { BikeService } from ‘../bike.service’;

selector: ‘app-bikes’,
templateUrl: ‘./bikes.component.html’,
styleUrls: [‘./bikes.component.css’]
export class BikesComponent implements OnInit {

bikes: Bike[];
selectedBike: Bike;
newBike: Bike;

constructor(private router: Router, private bikeService: BikeService) {


ngOnInit() {
this.bikeService.getBikes().then(bikes => this.bikes = bikes);
this.newBike = new Bike();

createBike(bike: Bike): void {

  .then(bike => {
    this.selectedBike = null;


deleteBike(bike: Bike): void {
.then(() => {
this.bikes = this.bikes.filter(b => b !== bike);
if (this.selectedBike === bike) { this.selectedBike = null; }

showInfo(bike: Bike): void {
this.selectedBike = bike;

  • createBike(bike: Bike) : Invokes createBike(bike: bike) from BikeService and pushes current bike in bikes array.
  • deleteBike(bike : Bike): invokes deleteBike from BikeService and nullifies selectedBike.

Angular 4 CRUD example is almost done. We just need to modify AppModule to include animations.


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

import { AppComponent } from './app.component';
import { BikeInfoComponent } from './bike-info/bike-info.component';
import { BikesComponent } from './bikes/bikes.component';
import { BikeService } from './bike.service';

import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
import { BikesDatabaseService } from './bikes-database.service';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { AppRoutingModule } from './app-routing/app-routing.module';
import { MaterialModule, MdList, MdListItem } from '@angular/material'

  imports: [
  declarations: [
  bootstrap: [AppComponent],
  providers: [BikeService],
export class AppModule { }


import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';

import { BikeInfoComponent } from '../bike-info/bike-info.component';
import { BikesComponent } from '../bikes/bikes.component';

const routes: Routes = [
  { path: 'information/:id', component: BikeInfoComponent },
  { path: 'bikes', component: BikesComponent }

  imports: [
  exports: [
  declarations: []
export class AppRoutingModule { }