Typescript Classes: How to initialize variables that require multiple promises?

Issue

My objective is to initialize the ‘page’ variable inside of the constructor. The issue is that I cannot perform make async/await promises inside of the constructor.
So my thought process was "Oh just make a method inside of the class, and call it inside of the constructor." But of course, I am wrong. Typescript still yells at me saying page is not being initialize definitively. Matter of fact, I am unable to call "newPage()" method onto the browser variable without async/await.
How can I get around this problem?
Thank you for your time in advance.

class Puppet {
  private page: puppeteer.Page;
  
  contructor() {
    this.initialize();
  }

  async initialize(){
    const browser = await puppeteer.launch({headless:true});
    this.page = await browser.newPage();
    await this.page.goto(this.url);
  }
}

Solution

From your calling method, first create the object, and then call the initialize() function:

class Puppet {
  private page!: puppeteer.Page;

  async initialize(){
    const browser = await puppeteer.launch({headless:true});
    this.page = await browser.newPage();
    await this.page.goto(this.url);
  }
}

// ... in some async function
const puppet = new Puppet();
await puppet.initialize();

If you want to make this a little more convenient, add an asynchronous factory function:

class Puppet {
  private page!: puppeteer.Page;

  async #initialize(){
    const browser = await puppeteer.launch({headless:true});
    this.page = await browser.newPage();
    await this.page.goto(this.url);
  }

  static async create() {
      const puppet = new Puppet();
      await puppet.#initialize();
      return puppet;
  }
}

// ... in some async function
const puppet = await Puppet.create();

This also allows you to hide your initialization in a private function.

Answered By – Robby Cornelissen

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published