I'm making my first App on Angular. I trying to filter a list of book objects by the gender attribute. I am having difficulty sharing data between components: the filteredData
variable and the list of books FireBaseList
.
I am trying to pass the filteredData
variable from fixed-nav.component
to books-grid.component
. From my research, I know I need to make the books-grid.component
"bookList" observable of any changes and have the bookList
on fixed-nav.component.ts
emit an event on any changes on this.bookList
However, I am unable to achieve this. I know there are many questions about observables already but none use Firebase. Hope anyone out there can help me, THANKS!!
fixed-nav.component that I use as filter
import { Component, OnInit } from '@angular/core';
import { BookService } from '../../../services/book.service';
import { Book } from '../../../models/book';
@Component({
selector: 'fixed-nav',
templateUrl: './fixed-nav.component.html',
styleUrls: ['./fixed-nav.component.css']
})
export class FixedNavComponent implements OnInit {
Genders: string[];
bookList: Book[];
constructor(private bookService: BookService) {
this.Genders = ["Historia","Literatura", "Infantil", "Juvenil","Poesía","Narrativa"];
}
filterByGender(gender: string){
this.bookService.getBooks() // FIREBASE
.snapshotChanges()
.subscribe(item => {
this.bookList = [];
item.forEach(element => {
let x = element.payload.toJSON();
x["$key"] = element.key;
this.bookList.push(x as Book)
})
const filteredData = this.bookList.filter( function(element){
return element.gender == gender;
});
return filteredData; // I WANT TO SHARE THIS DATA
})
}
ngOnInit() {
}
}
books-grid.component.ts
import { Component, OnInit } from '@angular/core';
import { BookService } from '../../services/book.service';
import { Book } from '../../models/book';
@Component({
templateUrl: './books-grid.component.html',
styleUrls: ['./books-grid.component.css']
})
export class BooksGridComponent implements OnInit {
bookList: Book[];
constructor(private bookService: BookService) {}
ngOnInit() {
this.bookService.getBooks() // FIREBASE
.snapshotChanges()
.subscribe(item => {
this.bookList = [];
item.forEach(element => {
let x = element.payload.toJSON();
x["$key"] = element.key;
this.bookList.push(x as Book)
})
// SHARED DATA HERE
})
}
}
book.service.ts
import { Injectable } from '@angular/core';
import { AngularFireDatabase, AngularFireList } from 'angularfire2/database';
import { Book } from '../models/book'; // Model
@Injectable({
providedIn: 'root'
})
export class BookService {
bookList: AngularFireList<any>;
selectedBook: Book = new Book(); // Temporally save selected Book
constructor(private firebase: AngularFireDatabase) { }
getBooks(){
return this.bookList = this.firebase.list('books');
}
}
books.model.ts
export class Book {
$key: string;
title: string;
author: string;
gender: string;
language: string;
image: string;
likes: number;
price: number;
new: boolean;
}
In your book.service.ts
create a filterdData
variable and function to set filterdData
like below. Import Subject
using import { Subject } from 'rxjs';
filteredData = new Subject<any>();
setFilteredData(data) {
this.filteredData.next(data);
}
And then in your fixed-nav.component.ts
after done filtration set that filtered data like below
this.bookService.setFilteredData(filteredData);
Finally subscribe to the filteredData
in book.service.ts
from books-grid.component.ts
like below and assign the data into variable that you want.
constructor(private bookService: BookService) {
bookService.filteredData.subscribe((data)=>{
// Assign the data into variable that you want e.g this.filteredData = data;
})
}
Hope this will helps you!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With