how to pass async value (promise) to click handler

85 views
Skip to first unread message

Nhut Thai Le

unread,
Oct 24, 2019, 5:43:40 PM10/24/19
to Angular and AngularJS discussion

Hello,

I have a template as follow:
<ion-content>
  <h3>Account#: {{ (customer | async)?.accountNo }}</h3>
  <h3>CustId: {{ (customer | async)?.id }}</h3>
  <h3>Name: {{ (customer | async)?.name }}</h3>
  <ion-button (click)="setDefault(customer)">
    Set As Default
  </ion-button>
</ion-content>

the customer is a Promise<Customer> that was retrieved earlier from a service call. So the properties of the Customer will displayed once the promise resolved. However, the promise is currently passed as is to the click handler, is there anyway i can pass the value of the promise only? something like (click)="setDefault(customer | async)" <------this doesnt work because pipe cause compilation error when used inside event binding 

Hervé Le Cornec

unread,
Oct 25, 2019, 1:30:26 AM10/25/19
to Angular and AngularJS discussion
Forget about "| async", just use the elvis operator as 
{{costumer?.name}}
Then initiate your component in the ngOnInit (or ngAfterViewInit), as doing this in the constructor won't be enough (you won't get the result of the promise).

By the way think about a store build with an Angular service to embed your costumer
{{store.costumer?.name}}

You will then be able to share this service between many components in a two-way data binding fashion : the change of the store.costumer in one component will natively propagate to all the other components using the store.

Hervé Le Cornec

unread,
Oct 25, 2019, 3:18:15 AM10/25/19
to Angular and AngularJS discussion
Here is your component, with a timeout to setup the customer in order to simulate an async process :
import { ComponentOnInit } from '@angular/core';

@Component({
  selector: 'app-mycomponent',
  templateUrl: './mycomponent.component.html',
  styleUrls: ['./mycomponent.component.css']
})
export class MycomponentComponent implements OnInit {

  customerany;

  constructor() { }

  ngOnInit() {

    setTimeout(()=> {
      this.customer = {
        name: 'Bob',
        age: 25
      }
    }, 1000);

  }
}

And here is the HTML template of the component :
<p>
  mycomponent works!
</p>
<ul>
  <li>name : {{customer?.name}}</li>
  <li>Age : {{customer?.age}}</li>
</ul>


Try to delete the ? of the elvis operator in the template : you get an error message.

This is all what you need. Isn't it great ?!

Cheers

Nhut Thai Le

unread,
Oct 25, 2019, 3:09:51 PM10/25/19
to Angular and AngularJS discussion
Thank you Herve,

I'm new to angular so i'm leaning something everyday :D. Just one question though. Since the "customer" variable may not be set when the view is rendered so the {{}} is the mechanism that angular is asynchonously watch the var and render when the value is available? If it is then why or when should we use async pipe?

Thai

Hervé Le Cornec

unread,
Oct 25, 2019, 3:45:52 PM10/25/19
to Angular and AngularJS discussion
Hello Thai,

I answer to your questions in the two posts above (Angular async and store with async Angular).

You mention an error that many make : the two-way data binding in Angular is not stated by a tag in the template : neither {{myvar}}, nor [(myvar)], or any other way. The two-way data binding is perpetual, included natively, and always present in Angular. You just control it by using its displays ({{myvar}},[(myvar)], [myvar], and so on). So the use of these HTML syntaxes are just made to control the fundamental two-way data binding. 
And that is f#?!@ powerful.

Please do look at the examples that I give, with codes,  in the two above posts.

Cheers
Hervé
Reply all
Reply to author
Forward
0 new messages