Reputation: 23
I started tinkering with JavaScript (Node) recently, and I'm having a problem with a function that performs file writing. This function is always executed last, regardless of the calling order, and I can't fix it, could someone help me? (For example, in the code below, the categorySumPrice() function should run after the createAndWriteFixedJsonFile() function, but it runs before) This is the program:
// ********************* CLASSES ****************
class Produto {
constructor(id, name, quantity, price, category) {
this.id = id
this.name = name
this.quantity = quantity
this.price = price
this.category = category
}
}
// ********************* Procedural *************
// ------ Global variables
// vector of objects produto
var produtos = []
// file name
const fileName = "broken-database.json"
//fixed file name
const fixedFileName = "./arquivo.json"
// file open require
const fs = require("fs")
//Read and Writing modes, like C
/*
r - Open file for reading
r+ - Open file for reading and writing
rs - Open file for reading synchronous mode
rs+ - Open file for reading and writing, synchronous mode
w - Open file for writing synchronous mode (if not exists file, created that)
wx - Open file for writing (if not exists file, dont created that)
w+ - Open file for writing and reading (if not exists file, created that)
wx+ - Open file for writing and reading (if not exists file, dont created that)
*/
// Fix JSON Part
// open broken database
var jsonFileName = openFile(fileName)
//read json file, fix, if necessary, and create objects produto
readFile(jsonFileName)
//save new JSON file fixed
createAndWriteFixedJsonFile(fixedFileName)
//sum price functions
categorySumPrice()
// ********************* FUNÇÕES *************
// Open File
function openFile(_file_name) {
try {
console.log('********************************')
console.log('* Arquivo aberto com sucesso *')
console.log('********************************')
return fs.readFileSync(_file_name, 'utf-8')
} catch (err) {
console.error(err)
}
}
// Fix JSON File and create objects produto
function readFile(_json_File) {
// Create produtos objects
try {
console.log('********************************')
console.log('* Os dados serão corrigidos, *')
console.log('* se necessário. *')
console.log('********************************')
const data = JSON.parse(_json_File)
for (var i in data) {
produtos[i] = new Produto(parseInt(data[i].id), fixString(data[i].name),
fixQuantity(data[i].quantity), fixPrice(data[i].price), data[i].category)
}
console.log('********************************')
console.log('* Dados obtidos com sucesso *')
console.log('********************************')
}
catch (err) {
console.log(`Erro: ${err}`)
}
}
// create and write fixed Json file
function createAndWriteFixedJsonFile(_fixedFileName) {
try {
fs.writeFile(_fixedFileName, JSON.stringify(produtos, null, 2), err => {
if (err) {
console.log(err)
}
else {
console.log('********************************')
console.log('* Arquivo criado com sucesso *')
console.log('********************************')
}
})
} catch (err) {
console.error(err)
}
}
function fixQuantity(quantityToFix) {
let quantity
if (isNaN(quantityToFix)) {
quantity = 0
}
else {
quantity = parseFloat(quantityToFix)
}
return quantity
}
function fixPrice(priceToFix) {
return parseFloat(priceToFix)
}
// Fix string function
function fixString(stringToFix) {
// Quatro tipos de erros conhecidos:
/*
"a" por "æ",
"c" por "¢",
"o" por "ø",
"b" por "ß".
*/
// o /g significará que todos os valores correspondentes serão substituídos.
// por padrão, replace substitui somente a primeira ocorrência
stringToFix = stringToFix.replace(new RegExp(/æ/g), "a");
stringToFix = stringToFix.replace(new RegExp(/¢/g), "c");
stringToFix = stringToFix.replace(new RegExp(/ø/g), "o");
stringToFix = stringToFix.replace(new RegExp(/ß/g), "b");
return stringToFix
}
function categorySumPrice() {
let estoquePorCategoria = []
let indice
let countCategories = 0
for (var i in produtos) {
if (i === 0) {
estoquePorCategoria[countCategories] = { categoria: produtos[i].category, valor: (produtos[i].quantity * produtos[i].price) }
countCategories++
}
else {
indice = estoquePorCategoria.indexOf(estoquePorCategoria.filter(function (obj) {
return obj.categoria == produtos[i].category;
})[0]);
if (indice != -1) {
estoquePorCategoria[indice].valor += (produtos[i].quantity * produtos[i].price)
}
else {
estoquePorCategoria[countCategories] = { categoria: produtos[i].category, valor: (produtos[i].quantity * produtos[i].price) }
countCategories++
}
}
}
console.log(estoquePorCategoria)
}
Upvotes: 2
Views: 899
Reputation:
writeFile
is an asynchronous function, which means that it will execute in parallel to other things. So:
writeFile
then it starts writing.writeFile
finishes writing.In order to have it execute synchronously with your other code you need to use writeFileSync
.
You should use writeFile
when the rest of your code isn't dependent on that file and writeFileSync
if it is.
Upvotes: 1
Reputation: 13110
fs.writeFile()
is executed asynchronously meaning that categorySumPrice()
comes ahead of createAndWriteFixedJsonFile()
because it takes time to save the file.
To avoid this you need to call categorySumPrice()
from the callback function in fs.writeFile()
:
// create and write fixed Json file
function createAndWriteFixedJsonFile(_fixedFileName) {
try {
fs.writeFile(_fixedFileName, JSON.stringify(produtos, null, 2), err => {
if (err) {
console.log(err)
}
else {
console.log('********************************')
console.log('* Arquivo criado com sucesso *')
console.log('********************************')
//And now is the time for executing the following:
categorySumPrice();
}
})
} catch (err) {
console.error(err)
}
}
Upvotes: 0
Reputation: 903
You can use fs.writeFileSync
, this will run according to your work flow.
Learn more about it here - https://www.geeksforgeeks.org/node-js-fs-writefilesync-method/
Upvotes: 0