Menu

Creating quick suburbs look up using ASP.NET Core web API and Angular 2 – part 2

In this tutorial I will be building a Australian suburb look up module using ASP.NET Core web API, as the second part I will create the client side, using Angular 2. Check out the part 1 for server side.

Below is the suburb.service.ts

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/of';

import { Suburb } from '../models';
import { BaseService } from './base.service';
import { LocalStorageService } from './local.storage.service';
import { HttpClient } from '../http.client';

@Injectable()
export class SuburbService extends BaseService {
    private apiUrl = 'api/Suburbs';
    private http;

    constructor(private httpClient: HttpClient, private storageService: LocalStorageService) {
        super();
        this.http = httpClient;
    }

    search(searchTerm: string): Observable<Suburb[]> {
        return this.http.get(this.apiUrl + "/Search?searchTerm=" + searchTerm)
            .map(this.extractData)
            .catch(this.handleError);
    }
}

I will be using the ng2-bootstrap typeahead for this one as it is super simple to integrate.

<div class="form-group" [ngClass]="{'has-error':!form.controls['suburb'].valid}">
	<label>Suburb</label>   
	<input formControlName="suburb" 
		autocomplete="off"
		[attr.maxlength]="75" 
		[typeahead]="suburbs" 
		(typeaheadLoading)="suburbsLoading($event)"
		(typeaheadOnSelect)="suburbOnSelect($event)"                            
		[typeaheadItemTemplate]="suburbItemTemplate"
		typeaheadOptionField="name"
		typeaheadWaitMs="300"
		placeholder="Suburb" 
		class="form-control" autocomplete="off">                               
	<template #suburbItemTemplate let-model="item">{{model.name}} {{model.postCode}} - <strong>{{model.state}}</strong></template>
	<span class="ng-typeahead-mini-loader" *ngIf="suburbLoading"><i class="fa fa-cog fa-spin"></i></span>
</div>

this is how CustomerDetailsComponent.ts  looks like which is using the typeahead

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { Observable } from 'rxjs/Observable';

import { SuburbService } from './../services/suburb.service';

import { TypeaheadMatch } from 'ng2-bootstrap/typeahead';

import {
    Suburb
} from './../models';

@Component({
    selector: 'customer-details',
    templateUrl: './details.component.html'

})
export class CustomerDetailsComponent implements OnInit {
    form: FormGroup;
    errorMessage: string;
    public suburbs: Observable<Suburb[]>;
    public suburbsSelected: string;
    public suburbLoading: boolean;

    private http;

    constructor(public fb: FormBuilder,
        private route: ActivatedRoute,
        private router: Router,
        private suburbService: SuburbService) {

    }

    ngOnInit() {
        var id: number;        
        this.form = this.initForm();
        this.initSuburbLookup();
		....
    }

    initForm() {
        return this.fb.group({
            ....
            suburb: ['', [Validators.required]],
            ....
        });
    }

    initSuburbLookup() {
        this.suburbs = Observable.create((observer: any) => {
            this.suburbService.search(this.form.value.suburb)
                .subscribe((data: any) => {
                    observer.next(data);
                });
        });
    }

    public suburbsLoading(e: boolean): void {
        this.suburbLoading = e;
    }

    public suburbOnSelect(e: TypeaheadMatch): void {      
		this.form.patchValue({
			state: e.item.state,
			postcode: e.item.postCode
		});       
    }
}

 

 

Leave a comment