0

Question is quite simple, in this code here

class Identifier {
    constructor(id) {
        if (/^[0-9]*$/.test(id)) {
            database.exists('users', {userid: id}).then(exists => {
                if (exists) {
                    this.id = id;
                } else {
                    throw 'id_not_exist';
                }
            });
        }
    }
}

I'm trying to set a property of the class as the result of a callback function. However, when executing this code

var ident = new Identifier(1);
console.log(ident.id);

The value returned is undefined, which seems to indicate the constructor function finishes before the callback is executed. Shouldn't the constructor block until the callback is complete? Is there a better way to do this?

1 Answers1

1

It's asynchronous, so it won't be done yet when new Identifier finishes.

Instead, offer a completion promise, probably from a setter rather than the constructor:

class Identifier {
    setId(id) {
        if (/^[0-9]*$/.test(id)) {
            return database.exists('users', {userid: id}).then(exists => {
                if (exists) {
                    this.id = id;
                    resolve(this);
                } else {
                    throw 'id_not_exist';
                }
            });
        } else {
            return Promise.resolve(this); // Assuming no ID is okay
        }
    }
}

let ident = new Identifier();
ident.setId(1)
    .then(_ => /*...it worked...*/)
    .catch(_ => /*...it failed...*/);

Alternately, if providing the ID in the constructor is important:

class Identifier {
    constructor(id) {
        if (/^[0-9]*$/.test(id)) {
            this.idPromise = database.exists('users', {userid: id}).then(exists => {
                if (exists) {
                    this.id = id;
                    resolve(this);
                } else {
                    throw 'id_not_exist';
                }
            });
        } else {
            this.idPromise = Promise.resolve(this); // Assuming no ID is okay
        }
    }
}

let ident = new Identifier(1);
ident.idPromise
    .then(_ => /*...it worked...*/)
    .catch(_ => /*...it failed...*/);

But you do need to check that that promise has resolved before expecting things to be complete.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875