Exercise - Read and write to files
You're almost finished creating a Node.js masterpiece for Tailwind Traders. So far, your code reads any folder, finds all .json
files, and creates a totals.txt
file in the salesTotals
folder.
In this exercise, you complete the project by reading the .json files
, adding up the store totals, and writing the grand total to the salesTotals/totals.txt
file.
Create a method to calculate sales totals
At the top of index.js, just below the
require("path")
statement, create a function that calculates the sales total. This method should take in the array of file paths that it can iterate over.async function calculateSalesTotal(salesFiles) { let salesTotal = 0; // READ FILES LOOP return salesTotal; }
Within that function, replace
// READ FILES LOOP
with a loop that:- (1) Iterates over the
salesFiles
array. - (2) Reads the file.
- (3) Parses the content as JSON.
- (4) Increments the
salesTotal
variable with thetotal
value from the file.
async function calculateSalesTotal(salesFiles) { // Final sales total let salesTotal = 0; // (1) Tterates over the `salesFiles` array. for (file of salesFiles) { // (2) Reads the file. const fileContents = await fs.readFile(file) // (3) Parses the content as JSON. const data = JSON.parse(fileContents); // (4) Increments the `salesTotal` variable with the `total` value from the file. salesTotal += data.total; } return salesTotal; }
- (1) Iterates over the
Call the calculateSalesTotals method
In the
main
function, modify the code to:- (1) Add a call to the
calculateSalesTotals
function just above thefs.writeFile
call. - (2) Modify the
fs.writeFile
block to write the value of thesalesTotal
variable to the totals.txt file.
async function main() { const salesDir = path.join(__dirname, "stores"); const salesTotalsDir = path.join(__dirname, "salesTotals"); try { await fs.mkdir(salesTotalsDir); } catch { console.log(`${salesTotalsDir} already exists.`); } const salesFiles = await findSalesFiles(salesDir); // (1) Add a call to the `calculateSalesTotals` function just above the `fs.writeFile` call. const salesTotal = await calculateSalesTotal(salesFiles); // (2) Modify the `fs.writeFile` block to write the value of the `salesTotal` variable to the *totals.txt* file. await fs.writeFile( path.join(salesTotalsDir, "totals.txt"), `${salesTotal}\r\n`, { flag: "a" } ); }
- (1) Add a call to the
Run the program
Run the program from the terminal.
node index.js
185933.76
Open the
./salesTotals/totals.txt
file to see the total of all the sales from the sales.json and totals.json files: 185933.76.Run the program from the terminal again.
node index.js
185933.76 185933.76
The totals.txt file now has a second line. Every time you run the program, the totals are added up again and a new line is written to the file.
Outstanding work! You've written a smart, robust, and handy tool that Tailwind Traders can use to process all of its stores' sales every night. In the next section, we'll review what you learned and a few tips to remember.
Got stuck?
If you got stuck during this exercise, here's the full code for this project.
const fs = require("fs").promises;
const path = require("path");
async function calculateSalesTotal(salesFiles) {
// Final sales total
let salesTotal = 0;
// (1) Tterates over the `salesFiles` array.
for (file of salesFiles) {
// (2) Reads the file.
const fileContents = await fs.readFile(file)
// (3) Parses the content as JSON.
const data = JSON.parse(fileContents);
// (4) Increments the `salesTotal` variable with the `total` value from the file.
salesTotal += data.total;
}
return salesTotal;
}
async function findSalesFiles(folderName) {
// (1) Add an array at the top, to hold the paths to all the sales files that the program finds.
let results = [];
// (2) Read the currentFolder with the `readdir` method.
const items = await fs.readdir(folderName, { withFileTypes: true });
// (3) Add a block to loop over each item returned from the `readdir` function using the asynchronous `for...of` loop.
for (const item of items) {
// (4) Add an `if` statement to determine if the item is a file or a directory.
if (item.isDirectory()) {
// (5) If the item is a directory, recursively call the function `findSalesFiles` again, passing in the path to the item.
const resultsReturned = await findSalesFiles(path.join(folderName, item.name));
results = results.concat(resultsReturned);
} else {
// (6) If it's not a directory, add a check to make sure the item name matches *sales.json*.
if (path.extname(item.name) === ".json")
results.push(`${folderName}/${item.name}`);
}
}
return results;
}
async function main() {
const salesDir = path.join(__dirname, "stores");
const salesTotalsDir = path.join(__dirname, "salesTotals");
// create the salesTotal directory if it doesn't exist
try {
await fs.mkdir(salesTotalsDir);
} catch {
console.log(`${salesTotalsDir} already exists.`);
}
// find paths to all the sales files
const salesFiles = await findSalesFiles(salesDir);
// read through each sales file to calculate the sales total
const salesTotal = await calculateSalesTotal(salesFiles);
// write the total to the "totals.json" file
await fs.writeFile(
path.join(salesTotalsDir, "totals.txt"),
`${salesTotal}\r\n`,
{ flag: "a" }
);
console.log(`Wrote sales totals to ${salesTotalsDir}`);
}
main();
Congratulations! You've read the files, parsed the JSON, and written the total to a file. You've completed the project!
Cleanup development container
After completing the project, you may wish to clean up your development environment or return it to its typical state.
Deleting the GitHub Codespaces environment ensures that you can maximize the amount of free per-core hours entitlement you get for your account.
Important
For more information about your GitHub account's entitlements, see GitHub Codespaces monthly included storage and core hours.
Sign into the GitHub Codespaces dashboard (https://github.com/codespaces).
Locate your currently running codespaces sourced from the
MicrosoftDocs/node-essentials
GitHub repository.Open the context menu for the codespace and select Delete.