So far every value was written into the program. A useful program takes information from the person running it and responds to what they type. The person running a program is called its user, and what they give the program is its input.
Two lines that read everything typed
A console program receives its input as text, through a channel called standard input. Normally standard input is the keyboard.
In Node, these two lines read everything the user types. You will write the same two lines in every program that reads input:
const fs = require("node:fs");
const lines = fs.readFileSync(0, "utf8").split("\n");
console.log(`Hello, ${lines[0]}!`);If the user types Ada, the program prints Hello, Ada!.
Here is what each part does, in the order Node carries it out:
require("node:fs")asks Node for a set of tools that comes with it. The set namedfsreads and writes files, and Node treats what the user types as one more file to read. The first line gives that set of tools the namefs.fs.readFileSync(0, "utf8")reads all of standard input and produces it as one string. The0is the number Node uses for standard input, and"utf8"says that you want the result as text..split("\n")cuts that string into pieces, one piece for each typed line. Inside a string,\nstands for the end of a line.- The result is a list of strings, which the second line names
lines. A list of values is called an array, and each value in it is an element.
To pick one value out of an array, write its position in square brackets after the name. Positions count from zero: lines[0] is the first line the user typed, lines[1] is the second and lines[2] is the third.
You do not need to remember every detail of those two lines yet. You need to know what they leave behind: an array named lines that holds the typed lines, in order.
const typed = "Ada\nLovelace"; // stands in for two typed lines
const lines = typed.split("\n");
console.log(lines[0]);
console.log(lines[1]);This example has no real input, so that it can run on the page: the string typed stands in for what a user would type. It prints Ada and then Lovelace.
Running programs that read input
The first example above has no Edit & run button, because the button supplies no input. Run it in the JavaScript playground instead:
- Copy the program into the editor.
- Open Standard input below the output and type what the user would type, one answer per line. For this program, type
Ada. - Press Run.
On your own computer, type node greet.js, then type the answers, each followed by Enter. When you have typed everything, press Ctrl+D on a new line (on Windows, Ctrl+Z and then Enter). That tells the program the input is complete, and only then does it carry on and print its reply. On Windows each typed line can also end with an extra invisible character. If a piece of typed text prints oddly there, write lines[0].trim(): .trim() removes spaces and invisible characters from both ends of a string. Number ignores them without help.
That is the honest limit of these two lines: the program reads all of its input first and answers afterwards. A program that replies after each typed line needs a way to wait in the middle of its work. Node does that with a technique that a later unit of this course builds up to. Everything else in this lesson stays true when you get there.
Say what to type before you read
Since the reading happens in one go, tell the user what to type before the program reads. A message that asks the user for input is called a prompt.
console.log("Type your name and press Enter.");
const fs = require("node:fs");
const lines = fs.readFileSync(0, "utf8").split("\n");
console.log(`Hello, ${lines[0]}!`);Statements run from top to bottom, so the prompt appears first. Then the program waits at readFileSync until the input is complete, and after that it prints the greeting. With Ada as the input, the output is:
Type your name and press Enter.
Hello, Ada!What you read is always text
Every element of lines is a string, even when the user types digits. That matters as soon as you calculate.
const answer = "36";
console.log(answer + 1);
console.log(answer + answer);This prints 361 and 3636. When one side of + is a string, + joins text instead of adding. The string "36" is two characters, a 3 and a 6. It is not the number thirty-six. JavaScript gives no error message here, so this mistake shows up only as a strange result.
Turn text into a number
The function Number takes a string that spells a number and returns that number.
const answer = "36";
const age = Number(answer);
console.log(age + 1);
console.log(Number("2.5") * 2);This prints 37 and 5. A function call can produce a value: programmers say the function returns it. Changing a value from one type to another is called converting it.
You can convert in the same statement that picks the line:
const age = Number(lines[1]);Read that from the inside out: lines[1] is the second typed line, Number converts it, and the name age refers to the result.
Step through this program to see the text become a number.
const typed = "Ada\n36"; // stands in for two typed lines
const lines = typed.split("\n");
const name = lines[0];
const age = Number(lines[1]);
console.log(`${name} will be ${age + 1}.`);Number converts the second one, and only then does + 1 mean arithmetic.Prompt, read, compute, print
Most small programs have the same four-part shape.
Here is a complete program in that shape. It works out the cost of some tickets.
// Prompt
console.log("Type the ticket price, then the number of tickets, each on its own line.");
// Read
const fs = require("node:fs");
const lines = fs.readFileSync(0, "utf8").split("\n");
// Compute
const price = Number(lines[0]);
const count = Number(lines[1]);
const cost = price * count;
// Print
console.log(`${count} tickets cost ${cost.toFixed(2)}`);Try it in the playground with this standard input:
4.5
3The output is:
Type the ticket price, then the number of tickets, each on its own line.
3 tickets cost 13.50Three mistakes you will meet
Text that does not spell a number. Number cannot convert "three", and it does not stop the program. It returns a special value that prints as NaN, which is short for "not a number". Any arithmetic that uses NaN gives NaN again.
const count = Number("three");
console.log(count);
console.log(count * 4.5);This prints NaN twice.
A line that was never typed. Asking an array for a position it does not have gives the special value undefined, which means "there is nothing here". Number(undefined) is NaN.
const typed = "4.5"; // the user typed one line, not two
const lines = typed.split("\n");
console.log(lines[1]);
console.log(Number(lines[1]) * 2);This prints undefined and then NaN. When you see NaN or undefined in your output, check two things: that each position in square brackets matches the order in which the lines are typed, and that the input has as many lines as the program reads. Remember that the first line is lines[0], not lines[1].
Leaving out the first reading line. This one does give an error message:
const lines = fs.readFileSync(0, "utf8").split("\n");
console.log(lines[0]);/work/main.js:1
const lines = fs.readFileSync(0, "utf8").split("\n");
^
ReferenceError: fs is not defined
at Object.<anonymous> (/work/main.js:1:15)ReferenceError means an unknown name, and the ^ points at fs. The name fs exists only after the line const fs = require("node:fs"); has run, so that line must come first.
What you can do now
You can read the lines a user types, pick each one out of the array by its position, convert text to a number and write programs in the prompt, read, compute, print shape. In the exercises you will predict what conversions print, then write a program that greets its user by name.
Next: make decisions with if and else, so that a program can respond differently to different input.