App libros Angular 7 + Bootstrap 4

Filtro de libros

<input type="text" class="form-control" [(ngModel)]="search">
...
<a class="card" *ngFor="let book of books.list | includes:search"></a>
ng generate pipe pipes/includes

includes.pipe.ts

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'includes'
})
export class IncludesPipe implements PipeTransform {

  transform(books:any, text:string): boolean {
    if (!text.length) return books;
    return books.filter((book:any) => (book.title.includes(text) || book.author.includes(text)));
  }

}

Guardando los libros

ng generate service services/books

books.service.ts

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

@Injectable({
  providedIn: 'root'
})

export class BooksService {
  list:any[] = [
    { id: 1, title:'Cuentos para ser escuchados', author:'Fernando Ruiz Rico', price:3.99, img:'https://images-na.ssl-images-amazon.com/images/I/41Xs%2BVAP-3L._SX331_BO1,204,203,200_.jpg', url:'https://www.amazon.es/dp/8461700511' },
    { id: 1, title:'Cuentos para ser compartidos', author:'Fernando Ruiz Rico', price:3.99, img:'https://images-na.ssl-images-amazon.com/images/I/41eWDLASNJL._SX331_BO1,204,203,200_.jpg', url:'https://www.amazon.es/dp/8409041294' },
    { id: 1, title:'La pandilla digital contra el profesor analógico', author:'Fernando Ruiz Rico', price:3.99, img:'https://images-na.ssl-images-amazon.com/images/I/518Kv-ZvfUL._SX331_BO1,204,203,200_.jpg', url:'https://www.amazon.es/dp/1719898235' }
  ];

  constructor() {
    var storage = localStorage.getItem('books-list');
    if (storage) this.list = JSON.parse(storage);
  }

  add(book:any) {
    this.list.unshift(book);
    this.save();
  }

  delete(item:number) {
    this.list.splice(item, 1);
    this.save();
  }  

  save() {
    localStorage.setItem('books-list', JSON.stringify(this.list));
  }
}

El resultado

Pulsa aquí.