Search code examples
node.jsangulartypescriptangular-servicesmongodb-atlas

How can I get one record in Angular issue?


I going to get one record of my database, And Now I just got a little mistake. I don't know how can I only get on the record. I had succeeded to get the record from my backend and I have console.log to show the value that I have got. Let me share my code.

and I have two pages, the first page is the home page for showing all book, here have no problem for show all book

The problem is here, in my book detail page. I have no idea how can I only show only one book when I click the book title of the book, I have seen I have got the backend response the value but I don't know how can I show it on my book detail page. I have no idea on the getOneBook subscribe

bookdetail html

<h1>Book-detail</h1>
<div *ngIf="book" class="bookdetail-block">
  <div *ngFor="let bookdetail of book" class="bookdetail">
    <h1>{{bookdetail.title}}</h1>
    <p><img [src]="bookdetail.image" ></p>
    <p>{{bookdetail.author}}</p>
    <p>{{bookdetail.price}}</p>
    <p>{{bookdetail.isbn}}</p>
    <p>{{bookdetail.description}}</p>

</div>
</div>

bookdetail ts

    export class BookDetailComponent implements OnInit {
  isbn: any;
  book: any;

  constructor(private data: DataService, private router: Router, private route: ActivatedRoute) { }

  ngOnInit() {

    this.route.snapshot.paramMap.get("isbn");

    this.data.getOneBook(this.isbn).subscribe(data =>{
      console.log({ data });  //show data
      this.book = data
      //console.log(this.books);
    })
  }

  getBookDetail(books) {
    this.data.getOneBook(books.isbn); //isbn of book
  }
}

the error here

 ERROR in src/app/bookdetail/bookdetail.component.ts(16,35): error TS2551: Property 'subscribe' does not exist on type 'Subscription'. Did you mean 'unsubscribe'?

And this is to get the response from the backend, please see the image data.service

home html

<h1>All Books</h1>
<ul *ngIf="books" class="info">
    <li *ngFor="let book of books">
       <p><img [src]="book.image" class="bookimg"></p>

        <a routerLink="/bookdetail/{{book.isbn}}" (click)="getBookisbn(book)"><h3>{{ book.title }}</h3></a>
        <p>{{ "By "+ book.author }}</p>
        <span class="price-block" >{{ "HKD$ " + book.price}}</span>

        <div class="btn-fav">
            <p>
            <button>Add to favorite</button>
            </p>
        </div>
        <div class="btn-cart">
            <p>
            <button>Add to cart</button>
            </p>
        </div>
    </li>
</ul>

home ts

export class HomeComponent implements OnInit {

  h1Style: boolean = false;
  books: Object;

  constructor(private data: DataService) {}

  ngOnInit() {
    this.data.getBooks().subscribe(data=> {
      console.log({data});  //show data
      this.books = data
      //console.log(this.books);
    })
  }

  // object of book
  getBookisbn(book) {
    this.data.getOneBook(book.isbn)   //isbn of book
    //this.router.navigateByUrl("bookdetail/" + book.isbn)
   }

data.service.ts

export class DataService {


  constructor(private http: HttpClient) { }

  getBooks() {
    return this.http.get('http://localhost:10888/book');
  }

  getOneBook(isbn:any) {
    // console.log("=============" + isbn )
    return this.http.get('http://localhost:10888/bookdetail/?isbn=' + isbn).subscribe(
      (val) => { // Get has no error and response has body
        console.log("Get successful value returned in body", val);
      },
      response => {
        console.log("Get call in error", response);
      },
      () => { // Get has no error, response has no body
        console.log("The Get observable is now completed.");
      });
  }

Solution

  • According to your Service:

    getOneBook accepts 1 parameter which is isbn

    so when you call it (subscribe) you should use

    this.data.getOneBook(this.isbn)
    

    rather than

    this.data.getOneBook(this.books)
    

    I assume you are including the isbn in the activated route as a parameter, so in this case, you may try code like this:

    //import { ActivatedRoute, Router } from "@angular/router";  
    
    export class BookDetailComponent implements OnInit {
      isbn: number;
      book: any;
    
      constructor(private data: DataService,
                  private router: Router,
                  private route: ActivatedRoute
                  ) {}
    
      ngOnInit() {
    
        this.isbn = this.route.snapshot.paramMap.get("isbn");
    
        this.data.getOneBook(this.isbn).subscribe(data =>{
          this.book = data
        })
      }
    }
    

    note that I replaced this.books with this.book as well.

    In your homecomponent HTML

    Replace

    <a routerLink="/bookdetail/{{book.isbn}}" (click)="getBookisbn(book)"><h3>{{ book.title }}</h3></a>
    

    With

    <a [routerLink]="['/bookdetail/', book.isbn]"><h3>{{ book.title }}</h3></a>