How to use Observable using Async channel inside Angular2 click function

Situation: I am using FirebaseObjectObservable to populate my Ionic 2 (rc0) template. Template Code:

<p>{{(course | async)?.description}}</p> <button ion-button dark full large (click)="openDeckOnBrowser(course.deckUrl)"> <ion-icon name='cloud-download'></ion-icon> <div>View Deck</div> </button> 

TS file

  this.course = this.af.database.object('/bbwLocations/courses/' + courseId); 

this.course - object of the Firebase Observable object. The problem is that this part will not work: (click) = "openDeckOnBrowser (course.deckUrl). Since the .deckUrl course is empty, I cannot pass the value of the function.

Tho is the only hacker way I've found work so far:

  <button id="{{(course | async)?.deckUrl}}" ion-button dark full large (click)="openDeckOnBrowser($event)"> <ion-icon name='cloud-download'></ion-icon> <div id="{{(course | async)?.deckUrl}}">View Deck</div> </button> 

And on the click event:

  openDeckOnBrowser(event):void { console.log(event); let target = event.target || event.srcElement || event.currentTarget; let idAttr = target.attributes.id; let url = idAttr.nodeValue; console.log (url); } 

But is there any official and easier way to approach this?

+5
source share
2 answers

In the template (click)="openDeckOnBrowser(course.deckUrl)" is evaluated immediately after parsing the template. You are not using an asynchronous channel here, therefore deckUrl empty. You can fix this by adding a second asynchronous pipe:

 <p>{{(course|async)?.description}}</p> <button ... (click)="openDeckOnBrowser((course|async).deckUrl)">...</button> 

However, this is not very pleasant since two subscriptions will be created.

Alternative A (better):

White papers in AsyncPipe always use *ngFor to display a list of items, not *ngIf to output a single item. The reason is simple: the *ngIf directive *ngIf not allow *ngIf . But we can get around this limitation:

The template is as follows:

 <div *ngFor="let course of course$|async"> <p>Course: {{course?.name}}</p> <p>Url: {{course?.url}}</p> </div> 

And in the component, we simply translate the course into a list of one course:

 this.getCourse().map(c=>[c]); 

See a working demo at Plunker

+7
source

Just subscribe to the observable in your code and save the course itself in the component:

 this.af.database.object('/bbwLocations/courses/' + courseId) .subscribe(course => this.course = course); 

Then you will see:

 <p>{{ course?.description }}</p> <button ion-button dark full large (click)="openDeckOnBrowser(course?.deckUrl)"> 

(although I would probably use ng-if and only show the description and button when the course is available)

+1
source

Source: https://habr.com/ru/post/1257696/


All Articles