Elo
Elo

Reputation: 306

JavaScript async, await, Promise, bug Unexpected token

It's needed to wait until the function getFile() ends. I call this async function in other function. In "async function getFile()" is bug: "Unexpected token. A constructor, method, accessor, or property was expected."

import { LightningElement } from 'lwc';

export default class ShoppingCart extends LightningElement {

  async function getFile() {  // <= here is an error: "Unexpected token. A constructor, method, accessor, or property was expected."
    let myPromise = new Promise(function(myResolve, myReject) {
      //let req = new XMLHttpRequest();
      //req.open('GET', "mycar.html");
      //req.onload = function() {
      //  if (req.status == 200) {myResolve(req.response);}
      //  else {myResolve("File not Found");}
      //};
      //req.send();
    });
    console.log(await myPromise);
  }

  handlePlaceOrder() {
    getFile();
  }

In this example it's ok. What I have wrong? Is it possible call async function in other than non async function?

I tried also an advice from this. To use first Promise, then async, but there is the same error:

import { LightningElement } from 'lwc';

export default class ShoppingCart extends LightningElement {

  function getFile() {  // <= here is an error: "Unexpected token. A constructor, method, accessor, or property was expected."
    let myPromise = new Promise(async function(myResolve, myReject) {
      //let req = new XMLHttpRequest();
      //req.open('GET', "mycar.html");
      //req.onload = function() {
      //  if (req.status == 200) {myResolve(req.response);}
      //  else {myResolve("File not Found");}
      //};
      //req.send();
    });
    console.log(await myPromise);
  }

  handlePlaceOrder() {
    getFile();
  }

I use VSCode.

Upvotes: 1

Views: 894

Answers (2)

goto
goto

Reputation: 4425

Classes have methods, so you need to drop the function keyword when declaring a class method:

class ShoppingCart extends LightningElement {
  getFile() { ... }
  handlePlaceOrder() { ... }
} 

Also, there's an issue with how you're calling getFile inside handlePlaceOrder. After you fix your issue, getFile becomes a class method, you need to call it as this.getFile(), so your fixed class should look like the following:

class ShoppingCard extends LightningElement {
  getFile() {
    return new Promise(
      function(resolve, reject) {
        let req = new XMLHttpRequest();
        req.open("GET", "mycar.html");
        req.onload = function() {
          if (req.status == 200) {
            resolve(req.response);
          } else {
            reject("File not found");
          }
        }
        req.send();
      }
    )
  }
}

Then, since getFile is an asynchronous call that returns a Promise, you need to handle it as such inside your handlePlaceOrder method:

class ShoppingCart extends LightningElement {
  getFile() {
    return new Promise(...);
  }

  handlePlaceOrder() {
    this.getFile()
      .then(function(result) {
        // do whatever
      })
      .catch(function(error) {
        // handle errors appropriately
      })
  }
}

Alternatively, make your handlePlaceOrder function async if it's making it easier for you to work with Promises:

class ShoppingCart extends LightningElement {
  getFile() {
    return new Promise(...);
  }

  async handlePlaceOrder() {
    try {
      let file = await this.getFile();
      // do whatever
    } catch (error) {
      // handle errors appropriately
    }
  }
}

Upvotes: 3

Supporterino
Supporterino

Reputation: 181

Edit: Look at goto1's solution it is more detailed

Like the comments suggest drop the function keyword. The keyword is only needed if you declare a function in a regular javascript outside of a class.

Furthermore you can't just await a promise. You need to call your promise and then await its result. This can be done like this: myPromise.then(result => {}).

Another thing in your function is that you aren't returning a value in your promise. You should call myResolve to pass the result of a successfull execution and myReject for an error.

You class should look like this:

import { LightningElement } from 'lwc';

export default class ShoppingCart extends LightningElement {

  async getFile() {
    let myPromise = new Promise(function(myResolve, myReject) {
      let req = new XMLHttpRequest();
      req.open('GET', "mycar.html");
      req.onload = function() {
        if (req.status == 200) {myResolve(req.response);}
        else {myResolve("File not Found");}
      };
      req.send();
    });
    myPromise.then(response => {
        console.log(response)
    });
  }

  handlePlaceOrder() {
    getFile();
  }
}

Upvotes: 1

Related Questions