javascript - What is the proper way to render an async function? - Stack Overflow

I have a function that fetches an object and returns a boolean from a check on the said object. I need

I have a function that fetches an object and returns a boolean from a check on the said object.

I need this boolean to decide what HTML should be the output of my render() function. When the function that checks the fetched object is called in my render() function, it always returns "undefined", as it always evaluates to true.

How should I proceed to output the correct value in proper timing? Thank you.

    async isGreenlisted() {
        return fetch(`${WEB_SERVICE_URL}/v2/banners/${this.viewId}`)
            .then(res => {
                for (let list in res) {
                    if (res[list].isDisplayed && list === "green") {
                        console.log("green true");
                        return true;
                    }
                }
                return false;
            });
    }

    render() {
        return html`
            <style>
                paper-button {
                    color: blue;
                }
            </style>
            <div>
                ${this.isGreenlisted()
            ? html`
                            <paper-button raised @click="${this._onClick}">Disable Powered By</paper-button>
                      `
            : html`
                            <paper-button raised @click="${this._onClick}">Enable Powered By</paper-button>
                      `}
            </div>
        `;
    }
}

I have a function that fetches an object and returns a boolean from a check on the said object.

I need this boolean to decide what HTML should be the output of my render() function. When the function that checks the fetched object is called in my render() function, it always returns "undefined", as it always evaluates to true.

How should I proceed to output the correct value in proper timing? Thank you.

    async isGreenlisted() {
        return fetch(`${WEB_SERVICE_URL}/v2/banners/${this.viewId}`)
            .then(res => {
                for (let list in res) {
                    if (res[list].isDisplayed && list === "green") {
                        console.log("green true");
                        return true;
                    }
                }
                return false;
            });
    }

    render() {
        return html`
            <style>
                paper-button {
                    color: blue;
                }
            </style>
            <div>
                ${this.isGreenlisted()
            ? html`
                            <paper-button raised @click="${this._onClick}">Disable Powered By</paper-button>
                      `
            : html`
                            <paper-button raised @click="${this._onClick}">Enable Powered By</paper-button>
                      `}
            </div>
        `;
    }
}
Share Improve this question edited Apr 15, 2020 at 12:15 Jocarol asked Apr 15, 2020 at 10:19 JocarolJocarol 471 silver badge7 bronze badges 7
  • 1 You could use a state for that purpose. – Gabriel L Martinez Commented Apr 15, 2020 at 10:22
  • async need to be used with await. In your case, you need to wait the fetch function to render the element. And, i thing that the idea of a state suggested by @GabrielLMartinez is a good approach. – William Prigol Lopes Commented Apr 15, 2020 at 10:42
  • In the for loop there is a return html``; after the if statement. Is this intended? It'll stop the loop at the first iteration and you're not actually rendering the returned template. – Umbo Commented Apr 15, 2020 at 10:49
  • @WilliamPrigolLopes Yes, my bad, i edited it out. What do you mean by not returning the template? – Jocarol Commented Apr 15, 2020 at 12:17
  • I believe that the idea on the @Umbo answer is the way, Show a loading state until the fetch is running. – William Prigol Lopes Commented Apr 15, 2020 at 12:23
 |  Show 2 more ments

2 Answers 2

Reset to default 11

isGreenlisted() returns a Promise so in the ternary operator you're essentially evaluating the promise itself instead of the value it will resolve to, and since class instances are truthy, the first template is always shown.

You should instead wait for the result of the promise, for example by using lit-html's until directive:

import {until} from 'lit-html/directives/until';

render() {
  return html`
  ${until(
    this.isGreenlisted().then(res => res
      ? html`True`
      : html`False`),
    html`Loading...`,
  )}
  `;
}

In case you prefer to use modern async/await syntax instead of explicit Promises with then(), you can do this in bination with the until directive:

render() {
    return html`
        ${until(
            (async () => {
                const greenListed = await isGreenlisted();
                greenListed ? return html`True` : return html`False`;
            })(),
            html`Loading...`
        )}
    `;
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1743879262a4522872.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信