Dealing with the challenge of passing a variable from a service (LibraryService) to a component located one level deeper in the directory structure (ReadingPaneComponent) has been quite troublesome for me. This predicament arose after successfully transferring the variable into the service from a component that is TWO levels deeper (AuthorsComponent). The ReadingPaneComponent, therefore, serves as an "aunt/uncle" to the AuthorsComponent, prompting my attempt to relay the variable through the existing LibraryService, which also facilitates fetching data from the backend database.
My goal is simply to transmit a numeric value of up to five digits, denoting the ID of a book, to the ReadingPaneComponent. While the service correctly detects the number, I find myself unable to pass it to the ReadingPaneComponent without it being interpreted as 'undefined'. Furthermore, I am invoking a method defined in the ReadingPaneComponent from the AuthorsComponent when the user clicks on a book title. Hence, the issue may stem from asynchronous calls or the placement of the method within the lifecycle hook of the ReadingPaneComponent (currently in ngOnInit, although I acknowledge this might not be the ideal location and have explored alternatives to no avail).
The following snippet pertains to library.service.ts: -
import { Injectable, Component, Input } from '@angular/core';
import { HttpClient, HttpResponse, HttpHeaders } from '@angular/common/http';
import { Language } from '../shared/language.model';
import { Author } from '../shared/author.model';
import { Book } from '../shared/book.model';
import { environment } from '../../environments/environment';
import { Observable } from 'rxjs/observable';
import { Subject } from 'rxjs/Subject';
import { AngularFireModule } from 'angularfire2';
import { AngularFireDatabaseModule } from 'angularfire2/database';
import {
AngularFireDatabase,
AngularFireList,
AngularFireObject } from 'angularfire2/database';
import { AngularFireAuthModule } from 'angularfire2/auth';
@Injectable()
export class LibraryService {
private chosenBookSource = new Subject<number>();
chosenBook$ = this.chosenBookSource.asObservable();
// MORE CODE HERE
chosenBook(data) {
console.log(data); //This displays the correct ID of the book clicked by the user, indicating that this function is operational.
this.chosenBookSource.next(data);
return data;
}
And here's an excerpt from reading-pane.component.ts: -
import { Component, OnInit, Input, OnDestroy } from '@angular/core';
import { LibraryService } from '../library.service';
import { Language } from '../../shared/language.model';
import { Author } from '../../shared/author.model';
import { Book } from '../../shared/book.model';
import { Observable } from 'rxjs/observable';
@Component({
selector: 'app-reading-pane',
templateUrl: './reading-pane.component.html',
styleUrls: ['./reading-pane.component.css'],
providers: [LibraryService]
})
export class ReadingPaneComponent implements OnInit, OnDestroy {
@Input() bookPGID: number;
public bookHTML;
constructor(private libraryService: LibraryService) {
}
ngOnInit() {
console.log(this.libraryService.chosenBook$);
this.libraryService.chosenBook$.subscribe(data => (this.bookPGID = data));
console.log(this.bookPGID);
this.libraryService
.loadBook(this.bookPGID)
.subscribe((book: Observable<any>) => (this.bookHTML = book));
}
The invocation in the AuthorsComponent indeed functions as intended since it triggers the loadBook
operation in the ReadingPaneComponent. However, the ID number fails to maintain its integrity during transportation from the LibraryService to the ReadingPaneComponent.
I would greatly appreciate any assistance offered.