Start learning free

LESSON 108 OF 348 · FOR LOOPS - LOOPING OVER ARRAYS

Looping Over Arrays in TypeScript: Fixing Buggy Code II

Practice Read the full explanation

Inside the code editor we've tried to write a for loop that prints a tailored message about every language in the languages array.

So when we ran the code, we expected it to print:

I think Python is cool!
I think Java is cool!
I think JavaScript is cool!

but it seems like we made some mistakes because when we run our code, it produces this output:

I think language is cool!
I think language is cool!
I think language is cool!

Assignment:

Your task is to fix our loop such that it will print the desired output.

STEP 1 OF 1
    Ctrl + Enter to check

    TYPESCRIPT · FOR LOOPS - LOOPING OVER ARRAYS

    Buggy Code For Loops 2 in TypeScript, explained

    What the code is supposed to do

    The program should print one sentence for each language in the languages array: I think Python is cool!, then the same sentence for Java, then for JavaScript. The code you start with runs without any error, but its output is wrong:

    let languages: string[] = ["Python", "Java", "JavaScript"];
    
    for (const language of languages) {
        console.log("I think language is cool!");
    }
    
    I think language is cool!
    I think language is cool!
    I think language is cool!
    

    The loop is doing its job: it runs three times, once per element. The problem is inside the loop body, and it is a bug that no error message will point out, because the program is perfectly valid.

    What goes wrong

    Everything between double quotes in TypeScript is plain text. The word language inside "I think language is cool!" is just text, the same as cool or think. It is not looked up as a variable. The string is identical on every pass, so the same sentence is printed three times.

    The loop variable language does change on every pass: it is "Python", then "Java", then "JavaScript". But a variable only affects the output where the code uses it as a value, outside of quotes. Here the code never uses it at all.

    A good habit when a loop prints the same thing every time: ask which part of the output should change from pass to pass, and check that this part comes from the loop variable.

    Fixing it step by step

    1. Find the part that should change. In the sentence, only the language name differs between lines. Everything else stays fixed.
    2. Cut the sentence around that part. The fixed text before it is I think , with a space at the end, and the fixed text after it is is cool!, with a space at the start.
    3. Join the pieces with the variable between them, either by concatenation or with a template literal.
    4. Run it and check the spaces: the output should read naturally, with one space on each side of the name.

    The fixed code in TypeScript

    let languages: string[] = ["Python", "Java", "JavaScript"];
    
    for (const language of languages) {
        console.log(`I think ${language} is cool!`);
    }
    

    The output is now:

    I think Python is cool!
    I think Java is cool!
    I think JavaScript is cool!
    

    This uses a template literal: text written between backticks instead of quotes. Inside it, ${...} marks a place where TypeScript evaluates what is between the braces and puts the result into the text. Here that is the current value of language.

    The concatenation alternative

    The same result comes from joining strings with +:

    for (const language of languages) {
        console.log("I think " + language + " is cool!");
    }
    

    Here the spaces have to be written inside the quoted pieces, next to the name. Leaving one out gives output such as I thinkPython is cool!. Template literals make it easier to see the final sentence, which is why they are the usual choice for messages with variables in them.

    Details worth knowing

    • Backticks, not quotes. ${language} is only replaced inside backticks. In a normal quoted string it is printed literally: 'I think ${language} is cool!' shows the characters ${language}.
    • Any expression fits. The braces can hold more than a name: ${2 + 2} produces 4.
    • Types vanish after compiling. The string[] annotation helps the editor and compiler, and plays no part when the program runs.
    • const in the loop header. Each pass gets a new language, so a const is fine.

    Common mistakes

    • Quotes instead of backticks. Writing "I think ${language} is cool!" with ordinary quotes prints the placeholder as text, so you get the same kind of wrong output as before.
    • Dropping a space. Both fixes depend on spaces around the name. Compare your output with the expected lines character by character.
    • Misspelling the variable. Writing ${languages} inserts the entire array, which prints as Python,Java,JavaScript, so each line would be wrong in a different way.
    • Changing the array or the loop. Nothing is wrong with them. The only line to change is the one inside the body.

    Checking your fix

    Run the code in the editor above. The three lines should differ only in the language name and match the expected output exactly, including the exclamation mark.

    Keep going with TypeScriptAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free