angularangular-renderer

Not updating the table data after inserting new record in angular 2


I am learning Angular 2. I am building a simple CRUD application using Angular 2. I am facing an issue, after inserting a record, the table is not refreshing in client side, however, it is inserting in the database. But if I reload the web page, it is updating the record, but if I add a new record, update a record, or delete a record not updating or refreshing the table. What's wrong with my code?

app.component.ts

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
}

app.component.html

<app-book></app-book>

book.component.ts

import {Component, OnInit, Output, EventEmitter} from '@angular/core';
import {BookService} from './book.service';
import {Book} from './book';

@Component({
    selector: 'app-book',
    templateUrl: './book.component.html'
})
export class BookComponent implements OnInit{
    books: Book[];
    statusMessage: string;
    book = new Book();
    constructor(private _bookService: BookService){}

    ngOnInit(): void {
        console.log("calling ngOnInit()::::");
        this.getBooks();
    }

    getBooks(): void{
        console.log("Inside getBooks():::::")
        this._bookService.getAllBooks()
            .subscribe((bookData) => this.books = bookData,
            (error) =>{
                console.log(error);
                this.statusMessage = "Problem with service. Please try again later!";
            });
        console.log("end of getBooks():::::")
    }

    addBook(): void{
        console.log("inside the addBook()::::::")
        this._bookService.addBook(this.book)
            .subscribe((bookData) => {console.log(bookData); this.books.push(bookData)},
            (error) =>{
                console.log(error);
                this.statusMessage = "Problem with service. Please try again later!";
            });
        this.getBooks();
        this.reset();
        console.log("end of addBook()::::");
    }

    updateBook(bookId: string){
        console.log("Inside the updateBook()::::::Book id::::"+bookId);
        this._bookService.getBookById(bookId)
            .subscribe((bookData) => this.book = bookData),
            (error) => {
                console.log(error);
                this.statusMessage = "Problem with service. Please try again later!";
            }
        this.getBooks();
        console.log("end of updateBook()::::::");
    }

    deleteBook(bookId: string){
        console.log("Inside the deleteBook()::::Book id::::"+bookId);
        this._bookService.deleteBook(bookId)
            .subscribe((response) => console.log(response),
            (error) =>{
                console.log(error);
                this.statusMessage = "Problem with service. Please try again later!";
            });
        this.getBooks();
        this.reset();
        console.log("end of deleteBook():::::::");
    }

    private reset(){
        console.log("inside the reset():::::::");
        this.book.title = null;
        this.book.author = null;
        console.log("end of reset():::::::");
    }
}

Even I tried calling the this.getBooks() method at the end of addBook(), deleteBook(), updateBook() but still its not refreshing or updating. It is only updating or refreshing when we reload the web page.

book.component.html

<div>
    <form>
        <input type = "hidden" [(ngModel)] = "book.id" name = "id" /> 
        <label>Book Title</label>
        <input type = "text" [(ngModel)] = "book.title" name = "title"/><br/>
        <label>Book Author</label>
        <input type = "text" [(ngModel)] = "book.author" name = "author"/><br/>
        <button (click) = "addBook()">Add Book</button>
    </form>
</div>
<div>
    <table border = "1">
        <tr>
            <td>Id</td>
            <td>Title</td>
            <td>Author</td>
            <td>Actions</td>
        </tr>
        <tr *ngFor = "let book of books">
            <td>{{book.id}}</td>
            <td>{{book.title}}</td>
            <td>{{book.author}}</td>
            <td>
                <button (click) = "updateBook(book.id)">Edit</button>      
                <button (click) = "deleteBook(book.id)">Delete</button>
            </td>
        </tr>
    </table>
</div>

book.service.ts

import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { Book } from './book';

@Injectable()
export class BookService{

    constructor(private _httpService: Http){}

    getAllBooks(): Observable<Book[]>{
        return this._httpService.get("http://localhost:8037/spring-mvc-restfull-crud-example/book")
                .map((response: Response) => response.json())
                .catch(this.handleError);
    }

    getBookById(bookId: string): Observable<Book>{
        console.log("Inside the getBookById() service::::::");
        return this._httpService.get("http://localhost:8037/spring-mvc-restfull-crud-example/book/"+bookId)
                .map((response: Response) => response.json())
                .catch(this.handleError);
    }

    addBook(book: Book){
        let headers = new Headers({ 'Content-Type': 'application/json' });
        let options = new RequestOptions({ headers: headers });
        if(book.id){    
            console.log("Inside addBook update service():::::::");
            return this._httpService.put("http://localhost:8037/spring-mvc-restfull-crud-example/book/"+book.id, JSON.stringify(book), options);
        }else{
            console.log("Inside addBook add service():::::::body:::::::"+JSON.stringify(book));
            return this._httpService.post("http://localhost:8037/spring-mvc-restfull-crud-example/book", JSON.stringify(book), options);
        }
    }

    deleteBook(bookId: string){
        console.log("Inside the service deleteBook():::::book id:::"+bookId);
        return this._httpService.delete("http://localhost:8037/spring-mvc-restfull-crud-example/book/"+bookId);  
    }

    private handleError(error: Response){
        console.error(error);
        return Observable.throw(error);
    }
}

app.module.ts

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


import { AppComponent } from './app.component';
import { BookService } from './book/book.service';
import { BookComponent } from './book/book.component';


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

What is wrong with my code ? Or How to do that ? Thanks in advance:)


Solution

  • Write this.getBooks() inside the subscribe function since it works ansynchronously.