Textual Progress Bar in Node.JS

Code to create a textual progress bar in Node.JS.

Textual Progress Bar in Node.JS

Recently I needed to diaplay a progress bar for one Node.JS program that runs in the console.

I found out it was rather easy but trickey, here is the code that I am using, these are two different functions that do the same thing.

function sleep(milliseconds) {
    return new Promise(res => setTimeout(res, milliseconds))
}

async function progressBarNoParams() {

    let totalOperations = 223;

    let lengthInChars = 54;
    let dotCounter = 0;
    let operationCounter = 0;

    for (i = 0; i < totalOperations; i++) {

        operationCounter = i + 1; // The number of operations doesn't start from 0 because is not an index

        dotCounter = Math.round((operationCounter * lengthInChars) / totalOperations);

        const dots = ".".repeat(dotCounter);
        const left = lengthInChars - dotCounter;
        const empty = " ".repeat(left);
        const progressCounter = Math.round((operationCounter * 100) / totalOperations);

        process.stdout.write(`\r[${dots}${empty}] ${progressCounter}%`);

        // console.log(` : ${dotCounter} , ${operationCounter}`); // Debug

        // Do something here ...
        await sleep(20);
        // ...

        operationCounter++;
    }

    console.log();
}

async function progressBarYesParams() {

    let totalOperations = 10;
    let dotCounter = 0;
    let operationCounter = 0;

    for (i = 0; i < totalOperations; i++) {

        operationCounter = i + 1; // The number of operations doesn't start from 0 because is not an index

        dotCounter = displayProgressBar(87, dotCounter, operationCounter, totalOperations);

        // Do something here ...
        await sleep(80);
        // ...

        operationCounter++;
    }

    console.log();
}

function displayProgressBar(lengthInChars, dotCounter, operationCounter, totalOperations) {

    dotCounter = Math.round((operationCounter * lengthInChars) / totalOperations);

    const dots = ".".repeat(dotCounter);
    const left = lengthInChars - dotCounter;
    const empty = " ".repeat(left);
    const progressCounter = Math.round((operationCounter * 100) / totalOperations);

    process.stdout.write(`\r[${dots}${empty}] ${progressCounter}%`);

    // console.log(` : ${dotCounter} , ${operationCounter}`); // Debug

    return dotCounter;
}

async function main() {

    // Start demo
    await progressBarNoParams();
    await progressBarYesParams();
}

main();

Here are the results:

Screenshot-from-2023-07-20-16-30-36