I'm new with NodeJS and Promises, so I might not been understanding how it works.
I'm loading a configuration file in my app, with the peculiarity that if it doesn't exist, I create it with the info from a call to database.
function getConfig(clientId, app) {
return new Promise(async (resolve, reject) => {
await fs.access(config.files.url_networks_file, async function(err) {
if (err) {
try {
await loadClientConfig(clientId);
} catch (e) {
reject(e);
}
}
});
fs.readFile(config.files.url_networks_file, 'utf8', function(err, data) { // Try to read network's configuration file
if (err) { // If file doesn't exists
reject(err);
} else if (JSON.parse(data)[app]) { // In case app's config exists
resolve(JSON.parse(data)[app]);
} else { // In case app's config doesn't exists
reject(new Error('There\'s no configuration for app: ' + app));
}
});
});
}
My problem is that fs.readFile()
doesn't waits until loadClientConfig()
finish, so it always return "file not found". If the config file already exists, it works perfectly.
I've tried putting fs.readFile()
inside the fs.access()
callback, still not getting anything (even if the file exists).
UPDATE
Still not working with the two solutions I received. I'm posting the code I made for each one to check if I lost something in the coding:
@Quentin
async function loadClientConfig(clientId) {
return new Promise((resolve, reject) => {
fs.access(config.files.url_networks_file, function (err) {
if (err) {
try {
sql.close();
sql.connect(config.database.credentials, function (err) {
if (err) {
reject(err);
} else {
var request = new sql.Request();
request.input('clientId', clientId);
query = config.database.queries.all;
request.query(query, function (e, data) {
if (e) {
reject(e);
} else {
try {
resolve(writeConfigFile(data.recordset));
} catch (err) {
reject(err);
}
}
});
}
});
} catch (e) {
reject(e);
}
}
});
});
};
async function getConfig(clientId, app) {
return new Promise(async (resolve, reject) => {
try {
await loadClientConfig(clientId);
} catch (e) {
reject(e);
}
fs.readFile(config.files.url_networks_file, 'utf8', function(err, data) { // Try to read network's configuration file
if (err) { // If file doesn't exists
reject(err);
} else if (JSON.parse(data)[app]) { // In case app's config exists
resolve(JSON.parse(data)[app]);
} else { // In case app's config doesn't exists
reject(new Error('There\'s no configuration for app: ' + app));
}
});
});
}
@dasfdsa
async function loadClientConfig(clientId) {
return new Promise((resolve, reject) => {
sql.close();
sql.connect(config.database.credentials, function(err) {
if (err) {
reject(err);
} else {
var request = new sql.Request();
request.input('clientId', clientId);
query = config.database.queries.all;
request.query(query, async function(e, data) {
if (e) {
reject(e);
} else {
try {
resolve(writeConfigFile(data.recordset));
} catch (err) {
reject(err);
}
}
});
}
});
});
};
async function getConfig(clientId, app) {
await new Promise((resolve, reject) => {
fs.access(config.files.url_networks_file, async function (err) {
if (err) {
try {
let temp = await loadClientConfig(clientId); /*Now that you told me its async, we will await it as well*/
resolve(temp);
} catch (e) {
reject(e);
}
} else {
resolve();
}
});
});
let configuration = await new Promise((resolve, reject) => {
fs.readFile(config.files.url_networks_file, 'utf8', function (err, data) { // Try to read network's configuration file
if (err) { // If file doesn't exists
reject(err);
} else if (JSON.parse(data)[app]) { // In case app's config exists
resolve(JSON.parse(data)[app]);
} else { // In case app's config doesn't exists
reject(new Error('There\'s no configuration for app: ' + app));
}
});
});
return configuration;
}
UPDATE 2
It seems that works when debugging, I'm using VSCode. I think it may be a timeout issue or something similar.
Code: Two separate awaited
promise
for each callback. getConfig
returns a promise
which will resolve to config
.
async function getConfig(clientId, app) {
await new Promise((resolve, reject) => {
fs.access(config.files.url_networks_file, async function (err) {
if (err) {
try {
let temp = await loadClientConfig(clientId);/*Now that you told me its async, we will await it as well*/
resolve(temp);
} catch (e) {
reject(e);
}
}
});
});
let config = await new Promise((resolve, reject) => {
fs.readFile(config.files.url_networks_file, 'utf8', function (err, data) { // Try to read network's configuration file
if (err) { // If file doesn't exists
reject(err);
} else if (JSON.parse(data)[app]) { // In case app's config exists
resolve(JSON.parse(data)[app]);
} else { // In case app's config doesn't exists
reject(new Error('There\'s no configuration for app: ' + app));
}
});
});
return config;
}
Edit: I have edited to await loadClientConfig()
, above code should work fine if loadClientConfig
returns a promise.