26

I need to pass async variable to the function. Something like this:

<div class="team" (click)="addToFavorite((match | async)?.id)">

And of course I have an error.

Parser Error: Cannot have a pipe in an action expression.

Maybe there is a way to transform async variable in JavaScript?

5
  • Would be kind if you'd let us know what the error is. Commented Oct 28, 2016 at 7:26
  • Worth a try (click)="match.then(val => addToFavorite(val?.id))" Commented Oct 28, 2016 at 7:27
  • @GünterZöchbauer ``` Parser Error: Cannot have a pipe in an action expression. ``` Commented Oct 28, 2016 at 7:31
  • @GünterZöchbauer Thanks for quick reply! It didnt work. polyfills.js:3 Unhandled Promise rejection: Template parse errors: Parser Error: Unexpected token > Commented Oct 28, 2016 at 7:35
  • Then you probable need to define a helper method Commented Oct 28, 2016 at 7:36

5 Answers 5

40

Here is how I solved it :

<div *ngIf="(match | async) as match" class="team" (click)="addToFavorite(match.id)">

It's short, simple and it works.

<ng-container *ngIf="(match | async) as match">
   <div class="team" (click)="addToFavorite(match.id)">
   </div>
</ng-container>

Update January 20th 2021

To be more clear I would name match observable source as match$.

And we can now use the new @ngrx/component package and use the new ngrxLet structural directive :

<ng-container *ngrxLet="match$ as match">
  <div class="team" (click)="addToFavorite(match.id)">
  </div>
</ng-container>

The async pipe is no more necessary. More info on ngrx.io, on this link.

Sign up to request clarification or add additional context in comments.

1 Comment

I like this answer as it all template-driven
18

Another option for simple variables and without any observables is writing value of the variable into hidden input:

<div *ngIf="(match | async)?.id">
    <input  #myControl [value]="(match | async).id" type="hidden" />
    <div class="team" (click)="addToFavorite(myControl.value)">
</div>

3 Comments

Very good workaround! However, I could only get this working, without the *ngIf wrapper around the input and button.
Awesome! Could be the sollution
This approach isn't working with boolean values, because *ngIf won't work with false
1

You can't do it in template.

But you can:

<div class="team" (click)="addToFavorite()">

and in your .component.ts:

public addToFavorite() {
  this
    .match  // should retain last value (e.g. use BehaviorSubject)
    .first() // completes after passing one value only
    .subscribe(
      (matchValue) => {
        // your logic here
    });
}

Note: We are subscribing (and immediately unsubscribing), similarly async pipe subscribes to Observable.

1 Comment

Thanks for your answer!
1

What about:

<div class="team" (click)="addToFavorite(match)">

and then in your code:

addToFavorite(obs: Observable<any>) {
  obs.take(1).subscribe(value => {
    addToFavoriteById(value.id);
  });
}

2 Comments

I have console error ` inline template:12:38 caused by: obs.take is not a function`
You need to import operators like .take()
1

Seems you need to use a helper method:

<div class="team" (click)="onClick(match)">
class MyComponent {
  onClick(event) {
    event.then(val => this.addToFavorite(val?.id);
  }
  addToFavorite(val) {
  }
}

4 Comments

I cannot use this val?.id so I just pass value and I still get observable in the addToFavorite() not a value itself
Why can't you use val?.id?
As far as I can tell, the ? operator is only available inside angular 2 templates, and not inside Typescript component code. This feature hasn't been implemented yet for Typescript, but It seems to be in the works: github.com/Microsoft/TypeScript/issues/16
@DevonSams thanks. I'm so used to it from Dart, I missed that it's not yet in TS. You are right, currently it is only available in template bindings.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.