0
votes

i have problem with observable and async pipe. I have input in my component with Observable. In controller and on subscribe into observable in ngOnInit im get valid values. Problem is in template, I do not get valid values on template. I want to have async in image src attribute.

TvShowComponent (return Observable)

    public getCoverLink(): Observable<string> {
      return this.tvShowForm.get('cover').valueChanges.pipe(map((coverLink:  string) => {
        return coverLink;
      }));
  }

TvShowComponent template (using nested component)

<fp-cover-thumbnail [coverLink$]="getCoverLink()"></fp-cover-thumbnail>

CoverThumbnailComponent (with Input()) @Input() public coverLink$: Observable;

ngOnInit() {
    this.coverLink$.subscribe(data => {
        console.log(data); // works here
    });
}

CoverThumbnailComponent template (but not works here :( )

<div class="cover-thumbnail-container">
<img #cover [src]="(coverLink$ | async)"> <!-- here not work -->
coverLink: {{ (coverLink$ | async) }} <!-- also here not work -->
</div>
1
At each change detection, getCoverLink() is called, and it creates and returns a new Observable. So you keep passing different observable again and again to your component. Either create the observable once and for all, and pass it, or just don't pass an observable, and pass the value of the cover input directly.JB Nizet

1 Answers

3
votes

The issue is this line:

<fp-cover-thumbnail [coverLink$]="getCoverLink()"></fp-cover-thumbnail>

You are passing a method that returns Observable<string> well, that doesn't work in Angular.

You need to make a Observable<string> and assign it to that. Ex.

coverLink$: Observable<string>;

Then on ngOnInit or whereever you want to call the method.

this.coverLink$ = this.getCoverLink();

Your html then becomes <fp-cover-thumbnail [coverLink$]="coverLink$"></fp-cover-thumbnail>

Alternatively you don't need to pass in an Observable to your child component you can just do <fp-cover-thumbnail [coverLink]="coverLink$ | async"></fp-cover-thumbnail>, where your Input() on your child component can be just a string now.