1

I want to output questions and receive answers as input in a terminal. For each question, there is a check, in this case if the input was provided or not. If it is, next question should be outputted; if not, question should be looped.

If input is provided every time, resolve() gets called and moves on to the next question, as it should. But the problem happens if the first time an empty input is sent. It kinda gets stuck and the resolve() does not work any more

const rdline = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

let userName, userSurname = "";

1st question

const question_name = () => {
    return new Promise((resolve) => {
        rdline.question("What's your name?\n", name => {
            if (name) {
                userName = name;
                resolve();
            } else {
                question_name();

            }
        });
    });

};

2nd question

const question_surname = () => {
    return new Promise((resolve) => {
        rdline.question("What's your surname?\n", surname => {
            if (surname) {
                userSurname = surname;
                resolve();
            } else {
                question_surname();
            }
        });
    });
};

call both questions

const askUser = async () => {
    await question_name();
    await question_surname();
    console.log(`Hi, ${userName} ${userSurname}`);
    rdline.close();
};

askUser();
DemiA
  • 333
  • 1
  • 11
  • `userName` and `userSurname` do not exist inside `askUser`. – evolutionxbox Dec 20 '21 at 15:51
  • Doing things recursively instead of with a simple loop means that you're creating a new Promise on each recursive call. – Pointy Dec 20 '21 at 16:07
  • @Pointy but why does `resolve()` does not actually resolve the promise when input is passed and code enters the `if` block? – DemiA Dec 20 '21 at 18:26

2 Answers2

1

It seems you're not resolving the data and are expecting userName and userSurname to exist in askUser.

Instead resolve the answers, and the repeat questions, and assign them inside askUser:

// mock rdline
const rdline = {
  question: (a,b) => a.match(/surname/) ? b('Test') : b('User'),
  close: () => {}
};

const question_name = () => {
    return new Promise((resolve) => {
        rdline.question("What's your name?\n", name => {
            if (name) {
                resolve(name);
            } else {
                resolve(question_name());
            }
        });
    });

};

const question_surname = () => {
    return new Promise((resolve) => {
        rdline.question("What's your surname?\n", surname => {
            if (surname) {
                resolve(surname);
            } else {
                resolve(question_surname());
            }
        });
    });
};

const askUser = async () => {
    const userSurname = await question_name();
    const userName = await question_surname();
    console.log(`Hi, ${userName} ${userSurname}`);
    rdline.close();
};

askUser();
evolutionxbox
  • 3,932
  • 6
  • 34
  • 51
  • `userName` and `userSurname` does exist in `askUser()`. It takes them from higher scope where they are defined. Plus, if the input is passed with each question, it works fine and `console.log("Hi, ${userName} ${userSurname}");` is outputted correctly. Also, `resolve()` works fine and questions are flowing, but as soon as one of the question receives an empty input, it just freezes. – DemiA Dec 20 '21 at 17:50
  • Adding `resolve()` in `else` block too fixed the issue, the variable declaration was not the issue. But, unfortunately I don't get theoretically why it was necessary to add `resolve()` in `else` block as well. – DemiA Dec 20 '21 at 18:22
  • 1
    @Demiko _"It takes them from higher scope where they are defined"_ - don't do this. [This is bad practice for async code.](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – evolutionxbox Dec 20 '21 at 18:51
0

There is a function called resolve in js. I suggest you do function questionname() {...} instead of calling an arrow function. Also, use another name instead of resolve.

Hermanboxcar
  • 418
  • 1
  • 13