0
class Example {
    constructor(id) {
        this.id = this.getId();
    }
    getId() {
        inquirer
            .prompt({
                message: "Enter id?",
                type: "input",
                name: "employeesId",
            })
            .then((answer) => (this.id = answer.employeesId));
    }
}

const testExample = new Example();
testExample.getId()
console.log(testExample.id); // <-- expected to log the id after user has entered it, instead returns undefined

So I'm new to OOP and just would like to understand why this won't work, any help would be appreciated.

A work around with explanation would also be highly appreciated.

Thanks in advance.

lewy192
  • 21
  • 6
  • 1st You didn't called `getId()`, also you need to return `Promise` from `getId()`, Because `inquirer.prompt()` return Promise ( It take time ) , At last you need to wait until `testExample.id` get modified, So first add return so it look like: `return inquirer`, Then call `testExample.getId().then(() => console.log(testExample.id))` – Nur May 01 '21 at 08:01
  • 1
    Unless required by a third party package, please switch to using async/await, code is much cleaner and you could reduce the coding lines in this to at least half. – CodeTrooper May 02 '21 at 00:59
  • 1
    "*How to Initialise class properties using inquirer js?*" - not at all. The prompt for values is not the responsibility of that class, and definitely not of the constructor. Get the values first, then construct the instance afterwards, using constructor parameters. See also [general advice on doing asynchronous stuff in a constructor](https://stackoverflow.com/a/24686979/1048572). – Bergi Jun 04 '21 at 21:26

1 Answers1

0

It takes a while for the then() callback to get called. But when you do this:

testExample.getId()
console.log(testExample.id);

You aren't waiting for the inquirer to finish and set the id. There's no way to wait for it right now because getId() is a void method. It needs to return a Promise.

The best way to do this is with async/await syntax. If you make getId() an async method then that means it will return a Promise that you can await.

It is not possible to definitely set the id to a number in the constructor because the constructor cannot be asynchronous. You can either have this.id be a Promise which resolves to a number or you can have it start out as undefined and then get set to a number once the inquirer is finished.

It looks like you are currently accepting an id as an argument to the constructor but you don't use it, so I'm not sure what's going on there.

With this.id as maybe undefined:

class Example {
    constructor() {
    }
    async getId() {
        const answer = await inquirer
            .prompt({
                message: "Enter id?",
                type: "input",
                name: "employeesId",
            });
        this.id = answer.employeesId;
    }
}

const testExample = new Example();
await testExample.getId();
console.log(testExample.id);

With this.id as a Promise:

class Example {
    constructor() {
        this.id = this.getId();
    }
    async getId() {
        const answer = await inquirer
            .prompt({
                message: "Enter id?",
                type: "input",
                name: "employeesId",
            });
        return answer.employeesId;
    }
}

const testExample = new Example();
const id = await testExample.id;
console.log(id);
Linda Paiste
  • 38,446
  • 6
  • 64
  • 102