I find it very hard to explain or search for this problem, so I'm asking Stack Overflow.
I'm asking user for user-input in the terminal several times and want to make a function out of it. A function that takes a question and a variable, and the input should be added to the variable.
This is my code:
var name = 'hello',
age = '11'
var readline = require('readline');
// var rl = readline.createInterface(process.stdin, process.stdout);
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
var getInput = function(inputVariable, question, cb) {
rl.question(question, function(answer) {
inputVariable = answer;
rl.close();
cb();
});
}
var askForName = function() {
console.log(1,age, name);
getInput(name, "What's your name? ", askForAge);
}
var askForAge = function() {
console.log(2,age, name);
getInput(age, "How old are you? ", printIt);
}
var printIt = function() {
console.log("Hello, " + name);
console.log(".. and " + age + " old.");
}
askForName();
Thanks!
I find it very hard to explain or search for this problem, so I'm asking Stack Overflow.
I'm asking user for user-input in the terminal several times and want to make a function out of it. A function that takes a question and a variable, and the input should be added to the variable.
This is my code:
var name = 'hello',
age = '11'
var readline = require('readline');
// var rl = readline.createInterface(process.stdin, process.stdout);
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
var getInput = function(inputVariable, question, cb) {
rl.question(question, function(answer) {
inputVariable = answer;
rl.close();
cb();
});
}
var askForName = function() {
console.log(1,age, name);
getInput(name, "What's your name? ", askForAge);
}
var askForAge = function() {
console.log(2,age, name);
getInput(age, "How old are you? ", printIt);
}
var printIt = function() {
console.log("Hello, " + name);
console.log(".. and " + age + " old.");
}
askForName();
Thanks!
Share Improve this question edited Jan 4, 2016 at 17:34 zer00ne 44.5k6 gold badges48 silver badges80 bronze badges asked Jan 4, 2016 at 17:28 RickBrunstedtRickBrunstedt 2,0012 gold badges15 silver badges12 bronze badges 3- 1 I'm not sure what you're asking for. – Michael Seltenreich Commented Jan 4, 2016 at 17:31
- 1 Don't pass to function variable you want to set. Instead use return value from the function. Or if you absolutely must pass variable - pass an object and set its properties inside of function. – Comfortably Numb Commented Jan 4, 2016 at 17:33
- maybe this helps: stackoverflow./questions/20086849/… – Nina Scholz Commented Jan 4, 2016 at 17:33
4 Answers
Reset to default 3In node.js applications, this is usually solved using either a callback chain or promises.
Using callbacks, you could write your code like this:
var getInput = function(question, cb) {
rl.question(question, function(answer) {
// Don't set the variable, but return value to callback
rl.close();
cb(answer);
});
}
// ask* take a callback which they call with the value
var askForName = function(cb) {
getInput("What's your name? ", cb);
}
var askForAge = function(cb) {
getInput("How old are you? ", cb);
}
// printIt takes the values as parameters
var printIt = function(name, age) {
console.log("Hello, " + name);
console.log(".. and " + age + " old.");
}
// Now ask for name and age and store them as local variables
// inside callbacks
askForName(function(name) {
askForAge(function(age) {
printIt(name, age);
});
});
I added ments to explain the changes. Basically, the values are only being passed between callbacks, never exposed to another scope.
When you pass a variable to a function, changing the reference to it will not affect the original variable. You can modify the variable's properties. However, that shouldn't be used as the main method of passing around variables.
A mon way of passing a response from an asynchronous process is to use a callback function. You've almost got it:
var getInput = function( question, cb ) {
rl.question(question, function(answer) {
rl.close();
cb(answer);
});
}
var askForName = function( cb ) {
getInput("What's your name? ", cb);
}
var askForAge = function( cb ) {
getInput("How old are you? ", cb);
}
var printIt = function( name, age ) {
console.log("Hello, " + name);
console.log(".. and " + age + " old.");
}
askForName(function(name) {
askForAge(function(age) {
printIt( name, age );
});
});
In javascript, only certain things are passed by reference
- they are objects
and arrays
. all other primitive types (strings, integers, etc.) are not.
With that being said, there are a number of ways for you to get what you are after here.. especially since age
and name
are essentially globals
(at least in the current scope of things)
One way is to just have the getInput()
method return
the value you want, and then assign that to your global
var. Another would be to just write setter
methods for each global
you're wanting to change. There are others, but those are the 2 easiest..
anyways, the following would resolve your issue:
var name = 'hello',
age = '11'
var readline = require('readline');
// var rl = readline.createInterface(process.stdin, process.stdout);
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
var getInput = function(inputVariable, question, cb) {
rl.question(question, function(answer) {
if( inputVariable === 'name' ) {
name = answer;
} else if( inputVariable === 'age' ){
age = answer;
}
rl.close();
cb();
});
}
var askForName = function() {
console.log(1,age, name);
getInput('name', "What's your name? ", askForAge);
}
var askForAge = function() {
console.log(2,age, name);
getInput('age', "How old are you? ", printIt);
}
var printIt = function() {
console.log("Hello, " + name);
console.log(".. and " + age + " old.");
}
askForName();
now, there are more elegant ways of doing this. for instance, you could create a map
, you could change the if statements to a switch
, you could have getInput
return a string via the callback
, etc.
you can use an Object
instead a primitive value, because objects are passed by reference, meaning the memory address of the original object will be affected.
In the following example, by leveraging that feature in objects, I also used the Function.prototype.call()
method, to set the execution context of the function (that is useful in case the answers
variable is not global.
//outer variable
var answers = {
name: "hello",
age: "11"
};
var readline = require('readline');
// var rl = readline.createInterface(process.stdin, process.stdout);
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
function getInput (propertyName, question, cb) {
var answers = this; //gets the context associated to the current function
rl.question(question, function(answer) {
answers[propertyName] = answer;
rl.close();
cb();
});
}
function askForName () {
console.log(1, answers);
//sets the execution context of getInput
getInput.call(answers, "name", "What's your name? ", askForAge);
}
function askForAge () {
console.log(2, answers);
//sets the execution context of getInput
getInput.call(answers, "age", "How old are you? ", printIt);
}
function printIt () {
console.log("Hello, " + answers.name);
console.log(".. and " + answers.age + " old.");
}