0

I have a pretty unique situation of assigning value to a variable inline using click event via an async function call. I have ng-template-for where a deeply nested and complex set of object is rendered on screen(e.g. comment of comment of comment and so on). So it is not possible to take the object and assign value by key or id once the function returns.

<button (click)="c.state = callState(c) ">Check</button>

Function is as follows:

async callState(c:any){
 let a = await http.call();
 return  Promise.all([a]);
}

Other 2 function variations return the same results:

   async callState(c:any){
     await http.call().then((res:any)=>{
       return res.
      });
    }

async callState(c:any){
 let a = await http.call();
 return  a;
}

I have tried many different variations of this, but the component view always get [object Promise]. It is supposed to pass a string. On inspection, the value is :

ZoneAwarePromise
__zone_symbol__state: true
__zone_symbol__value: [{…}]

Can someone help to assign a string from a simple http call inline on click to a view variable?

5
  • return Promise.all([a]) - this line returns a promise, it does not resolve promises. You need to await it or .then() to resolve it Commented Aug 23, 2023 at 18:32
  • I tried that too. The result in view remains the same. Commented Aug 23, 2023 at 18:37
  • Did you try using the async pipe in the template? Commented Aug 23, 2023 at 19:10
  • Could you just do the assignment inside your callState() method? something like this Commented Aug 23, 2023 at 19:15
  • @Loop, using the async pipe in the template was my first thought. When I try to use it within an event binding it gives the error No pipe found with the name ''. StackBlitz Commented Aug 23, 2023 at 19:18

1 Answer 1

1

ts file

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'projecttest';
  public c: any = {};

  constructor(private http: HttpClient) { }

  async updateState(c: any) {
    const result: any = await this.callState(c);
    // Assuming the result is an array, update index accordingly
    return result[0].title;
  }

  async callState(c: any) {
    const a = await this.http.get('https://jsonplaceholder.typicode.com/todos/1').toPromise();
    return Promise.all([a]);
  }
}

html template

<button (click)="c.state = updateState(c)">Check</button>
<div>{{ c?.state |async }}</div>

In your component, the updateState method now directly assigns the resolved value to c.state. Then, in your template, you're using the AsyncPipe to automatically unwrap and display the value of c.state once it's resolved.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.