Live Dashboard In Angular 2 Using Observable

In this tutorial, I will show you how to pull the data from back-end periodically to keep your UI up to date. In this tutorial, I will mainly focus on Observable, which is imported from rxjs/Rx. In this tutorial, I will use to-do Application, which is created previously to display the new task, add the new task, update the task and delete the task. You can find more about it here. In this tutorial, I am using the same project, which is available in GitHub.

First, start with creating addtask.component

Addtasks.component.html 

  1. [code language=”html”]  
  2. <div class="container">  
  3.    <div class="row">  
  4.    <form (ngSubmit)="taskSubmit()" #addform="ngForm">  
  5.       <div class="form-group">  
  6.         <label for="id">Id</label>  
  7.         <input type="number" [(ngModel)]="model.Id"   
  8.         name="id"   
  9.         class="form-control" id="id"  
  10.          required #id="ngModel">  
  11.       </div>  
  12.        <div [hidden]="id.valid || id.pristine"   
  13.              class="alert alert-danger">  
  14.           Task Id is required  
  15.         </div>  
  16.   
  17.       <div class="form-group">  
  18.         <label for="name">Task</label>  
  19.         <input type="text" [(ngModel)]="model.Title"   
  20.         name="title"   
  21.         class="form-control" id="name"  
  22.          required #title="ngModel">  
  23.       </div>  
  24.        <div [hidden]="title.valid || title.pristine"   
  25.              class="alert alert-danger">  
  26.           Task Title is required  
  27.         </div>       
  28.       <div class="form-group">  
  29.   <label for="power">Status</label>  
  30.   <select class="form-control" id="status"   
  31.   [(ngModel)]="model.Status" name="status"  
  32.    required>  
  33.     <option *ngFor="let s of status" [value]="s">{{s}}</option>  
  34.   </select>  
  35. </div>  
  36.       <button type="submit" class="btn btn-primary form-control" [disabled]="!addform.form.valid" >Add Task</button>  
  37.     </form>  
  38. </div>  
  39. </div>  
  40. [/code]  

Addtasks.component.ts 

  1. [code language=”typescript”]  
  2. import { Component, OnInit } from '@angular/core';  
  3. import { Task } from './task';  
  4. import { TaskdataService } from '../taskdata.service';  
  5. import { Router } from '@angular/router';  
  6. @Component({  
  7.   selector: 'app-addtask',  
  8.   templateUrl: './addtask.component.html',  
  9.   styleUrls: ['./addtask.component.css']  
  10. })  
  11. export class AddtaskComponent implements OnInit {  
  12. status = ['pending','done'];  
  13. model = {Id:'',Title:'',Status:'pending'};  
  14.   constructor(private _data:TaskdataService,private _router:Router) { }  
  15.   
  16.   ngOnInit() {  
  17.   }  
  18. taskSubmit(){  
  19.   
  20. this._data.addTask(this.model).subscribe(  
  21.   (data:any)=>{  
  22. this._router.navigate(['/allTask']);  
  23.   }  
  24. );  
  25. }  
  26. }  
  27. [/code]  

In the code given above, I used a template driven approach and using two way data binding, added a new task to the database. For more about add, update and delete task; use the the link given above.( https://jinalshahblog.wordpress.com/2016/12/28/crud-in-angular2-part2/)

Tasks.component.html 

  1. [code language=”html”]  
  2. <div class="row">  
  3.   <table class="table">  
  4.     <thead>  
  5.       <th>Id</th>  
  6.       <th>Title</th>  
  7.       <th>Status</th>  
  8.       <th>Action</th>  
  9.     </thead>  
  10.     <tbody>  
  11.       <tr *ngFor="let item of allTask ">  
  12.         <td>{{item.Id}}</td>  
  13.         <td>{{item.Title | uppercase}}</td>  
  14.         <td><span [ngClass]="{'pendingstatus': item.Status=='pending','donestatus':item.Status=='done'}" >{{item.Status}}</span></td>  
  15.         <td><button (click)="delTask(item)"><span class="glyphicon glyphicon-trash"></span></button>  
  16.               
  17.         </td>  
  18.       </tr>  
  19.     </tbody>  
  20.   </table>  
  21.   </div>  
  22. [/code]  

Tasks.component.ts 

  1. [code language=”typescript”]  
  2. import { Component, OnInit , OnDestroy } from '@angular/core';  
  3. import { Task } from './task';  
  4. import { TaskdataService } from '../taskdata.service';  
  5. import { Observable } from 'rxjs/Rx';  
  6. import {AnonymousSubscription} from "rxjs/Subscription";  
  7. @Component({  
  8.   selector: 'app-tasks',  
  9.   templateUrl: './tasks.component.html',  
  10.   styleUrls: ['./tasks.component.css']  
  11. })  
  12. export class TasksComponent implements OnInit {  
  13. allTask:Task[]=[];  
  14. private timerSubscription: AnonymousSubscription;  
  15.  private postsSubscription: AnonymousSubscription;  
  16.   constructor(private _data:TaskdataService) { }  
  17.   
  18.   ngOnInit() {  
  19. this.refreshData();  
  20.   }  
  21.   delTask(item:Task){  
  22.     event.stopPropagation();  
  23.   this._data.deleteTask(item).subscribe(  
  24.     (data:any)=>{  
  25.        this.allTask.splice(this.allTask.indexOf(item),1);   
  26.     },  
  27.     function(error){  
  28.     }      
  29.   );  
  30.   }  
  31.   public ngOnDestroy(): void {  
  32.         if (this.postsSubscription) {  
  33.             this.postsSubscription.unsubscribe();  
  34.         }  
  35.         if (this.timerSubscription) {  
  36.             this.timerSubscription.unsubscribe();  
  37.         }  
  38. }  
  39.   private subscribeToData(): void {  
  40.   
  41.   this.timerSubscription=Observable.timer(5000)  
  42.   .subscribe(()=>this.refreshData());  
  43.   }  
  44.  private refreshData():void{  
  45.     this.postsSubscription= this._data.getAllTask().subscribe(  
  46.       (data:Task[])=>{  
  47.         this.allTask=data;  
  48.         this.subscribeToData();  
  49.       },  
  50.       function(error){  
  51.         console.log(error);  
  52.       },  
  53.       function(){  
  54.         console.log("complete");  
  55.       }  
  56.     );  
  57.   }  
  58. }  
  59. [/code]   

Here, in the code given above, I created one method named as refreshdata, which will call the Service getAllTask which will fetch allTask from the database and on success of this method, I had given response/data to allTask array. Afterwards also call another method subscribeToData,which sets the timer of 5 seconds and then again call refreshdata. In this way, we can pull the data from the database.

Also, don’t forget to unsubscribe from subscribeToData on ngOnDestroy to prevent the memory leakage issue.

Output

  1. Two screens are there, where one displays record and one is for adding a  new task.



  2. First screen has still not received an update, while second screen added the record and navigated back to all the task, so it gets the updates.



  3. Finally, both screens get the record.(timer called after 5 seconds).


In this tutorial, I covered how to fetch the data periodically from the database to keep UI updated.

Find the source code here and feel free to play with the code yourself.

I hope, it will be helpful to you. Thanks for reading.