Good day,
I want a function to check if there are any files inside a folder, if there is no folder, make the folder and then run itself (function) again.
const fs = require('fs');
const writeFileAtomic = require('write-file-atomic');
class DataHandler {
constructor() {
}
}
DataHandler.prototype.checkDB = function() {
return new Promise((resolve, reject) => {
fs.readdir('./database', function (err, files) {
if (err) {
if (err.code = 'ENOENT') {
fs.mkdir('./database', () => {
return this.checkDB;
})
} else {
reject();
}
}
if (files) {
console.log(files)
}
})
})
}
module.exports = DataHandler;
I get errors using this, saying this.checkDB is not a function
The fix maybe is to save this in a variable:
DataHandler.prototype.checkDB = function() {
var dataHandler = this;
return new Promise((resolve, reject) => {
fs.readdir('./database', function (err, files) {
if (err) {
if (err.code = 'ENOENT') {
fs.mkdir('./database', () => {
return dataHandler.checkDB;
})
} else {
reject();
}
}
if (files) {
console.log(files)
}
})
})
}
A VERY basic explanation:
In javascript, when you put this inside of a function(){} it gets assigned to that function's object. Then, when you called fs.readdir(...., function(... { ... the keyword/variable this was binded to that function()'s object.. I recommend you this read: this - JavaScript | MDN
That binding does not happen with arrow functions, so, if you're curious there's another fix for your problem. You would need to replace function (err, files) with (err, files) =>, like this:
DataHandler.prototype.checkDB = function() {
return new Promise((resolve, reject) => {
fs.readdir('./database', (err, files) => {
if (err) {
if (err.code = 'ENOENT') {
fs.mkdir('./database', () => {
return this.checkDB;
})
} else {
reject();
}
}
if (files) {
console.log(files)
}
})
})
}
Seems like the object this refers to the Object created with the new Promise(.. I would suggest to log.console(this) and check what it contains
Related
I am receiving a list of objects from the front-end and i want to create multiple directories from the values stored in that key value pairs. So far I tried this method but it isn't working.
filercv=layerorder.map(layer=>{
return `layers/${layer.name}`;
})
console.log(filercv)
var count
function makeAllDirs(root, list) {
return list.reduce((p, item) => {
return p.then(() => {
console.log(item)
console.log(root)
return mkdirp(path.join(root,item));
});
}, Promise.resolve());
}
// usage
makeAllDirs(basePath,filercv).then(() => {
console.log('yes')
}).catch(err => {
// error here
console.log(err)
});
};
//layerorder
layerorder=[{"name":"bodies"},{"name":"Top"}]
But when i run this code only one folder is created in the layers directory i.e bodies.
check within mkdirp(), maybe your path resolves to somewhere else, so check the final constructed path, or maybe the recursive flag is missing: fs.mkdir(path)
Also, try async/await, this will create folders in process.cwd():
const fs = require('fs');
const path = require('path');
function mkdirp(dir) {
return new Promise((resolve, reject) => {
console.log('--creating dir: ', path.resolve(dir));
fs.mkdir(dir, {
recursive: true
}, (err) => {
if (err) reject(err);
resolve();
});
});
}
//layerorder
const layerorder = [{
"name": "bodies"
}, {
"name": "Top"
}];
const filercv = layerorder.map(layer => {
return `layers/${layer.name}`;
});
console.log('dirs: ', filercv);
// check path
let basePath = process.cwd();
async function makeAllDirs() {
try {
await Promise.all(filercv.map(dir => {
console.log(`root: ${basePath}, item: ${dir}`);
return mkdirp(path.join(basePath, dir))
}));
console.log('yes');
} catch (err) {
console.log('no', err);
}
}
makeAllDirs();
i'm trying to create a function to check exist and not exist file names so i used recursion function and proimse but unfortunately it's not resolve anything when the condition is true i tried it like that
function checkFileName(n = 0) {
return new Promise((resolve, reject) => {
fs.open("./npm"+n+".txt", 'r', function(err, res) {
if (err) {
resolve("./npm"+n+".txt")
} else {
n++
checkFileName(n)
}
})
})
}
checkFileName().then(Name => {
console.log(Name)
})
but it's not resolve anything where's the wrong ?
Any specific reason you is doing it like that ?
// Node.js program to demonstrate the
// fs.readdir() method
// Import the filesystem module
const fs = require('fs');
const path = require('path');
// Function to get current filenames
// in directory with specific extension
fs.readdir(__dirname, (err, files) => {
if (err)
console.log(err);
else {
console.log("\Filenames with the .txt extension:");
files.forEach(file => {
if (path.extname(file) == ".txt")
console.log(file);
})
}
})
Instead of reading a file at the time, you can read the hole dir and iterate over them returned files
Please change checkFileName(n) to checkFileName(n).then(resolve)
One of the solutions would be as follows:
function checkFileName(n = 0) {
return new Promise((resolve) => {
const filePath = "./npm"+n+".txt";
fs.open(filePath, 'r', function(err, res) {
if (err) {
resolve(filePath)
} else {
checkFileName(n+1).then(resolve)
}
})
})
}
checkFileName().then(Name => {
console.log(Name)
})
Noob in nodejs here and still trying to learn how nodejs works. Could you please let me know how can I pass the callback response from "getDatafromCosmosDB" function into a variable in the main function and print those values.
When I try to assign getDatafromCosmosDB to a variable "respdata" and try to print it, it is not working.
async function main(params, callback) {
const logger = Core.Logger('main2', { level: params.LOG_LEVEL || 'info' })
try {
logger.info('main action')
const respdata = getDatafromCosmosDB(function(response){
console.debug(response)
return response
});
console.debug(respdata)
} catch (e) {
console.debug(e)
}
}
exports.main = main
async function getDatafromCosmosDB(callback){
var query = new azure.TableQuery()
.top(5)
tableService.queryEntities('myCosmosTable', query, null, function (error, result, response) {
if (!error) {
console.log('success')
return callback(result.entries)
}
});
}
Try something like this,
import {
createTableService,
services,
ServiceResponse,
TableQuery
} from 'azure-storage';
getDatafromCosmosDB(): Promise<ServiceResponse> {
return new Promise(async (resolve, reject) => {
this.tableService.queryEntities(
this.tableName,
query,
null,
(error, _, response) => {
if (!error) {
resolve(response);
} else {
reject(error);
}
}
);
});
}
and invoke like,
this.getDatafromCosmosDB().then(data => {
console.log(data);
}
How can I use the answer of a promise outside of. Then what should I do?
arreglo.forEach((item) => {
if (item.tipoCampo == 3) {
self.campoSelects(item.tablaCampo)
.then(resp => {
console.log(resp)
})
.catch(e => console.log(e))
}
});
console.log (resp) inside the .then () knows it and prints correctly, but when I want to know resp out of the forEach to use below, it says undefined
Thanks.
arreglo.forEach((item) => {
if (item.tipoCampo == 3) {
self.campoSelects(item.tablaCampo)
.then(resp => {
logMyData(resp);
})
.catch(e => console.log(e))
}
});
logMyData=(x)=>{
console.log(x);
}
This is just as simple as adding a helper function which executes inside your .then
Guessing that you want to be able to access the value within the forloop. Since self.campoSelects is a promise we can use async await.
// Call campo selects
function getCampoSelects(_self, tablaCampo) {
return new Promise(async (resolve, reject) => {
let campoData;
try {
campoData = await _self.campoSelects(tablaCampo);
} catch (err) {
reject(err);
}
resolve(campoData);
});
}
function happyLittleFunc() {
const arreglo = [];
arreglo.forEach(async (item) => {
if (item.tipoCampo === 3) {
let campoSelect;
// Unsure if you are setting self somewhere but it can be passed in here.
try {
campoSelect = await getCampoSelects(self, item.tipoCampo);
} catch (err) {
console.log(err);
return;
}
console.log(campoSelect);
}
});
}
happyLittleFunc();
The Lambda function is not hitting the memory limit neither timing out. I read somewhere that it may return because the event loop is empty but I have context.callbackWaitsForEmptyEventLoop set to false.
Here is the function:
module.exports.callMenu = (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false;
const eventJSON = qs.parse(event.body);
myMongooseObject.findOne({ value: eventJSON.value }, (err, theObject) => {
if (!err) {
newObj = new myMongooseObject();
newObj.message = 'this worked';
newObj.save((err) => {
if (!err) {
callback(null, { body: 'success' });
} else {
console.log(err);
}
});
}
};
In your code, you are not adding callbacks for when there is an error in the request. And you may want to add a try/catch to handle any other issues with your code.
Also, you don't need to set callbackWaitsForEmptyEventLoop because you are not adding extra events besides your main request.
Try this:
const myMongooseObject = defineThisObject(); // maybe you forgot to define it
const qs = defineThisObjectToo(); // maybe another error
module.exports.callMenu = (event, context, callback) => {
try {
const eventJSON = qs.parse(event.body);
myMongooseObject.findOne({ value: eventJSON.value }, (err, theObject) => {
if (!err) {
newObj = new myMongooseObject();
newObj.message = 'this worked';
// define the newCall object too?
newCall.save((err) => {
if (!err) {
callback(null, { body: 'success' });
} else {
callback(err); // add this
}
});
} else {
callback(err); // add this
}
});
} catch (e) {
callback(e);
}
};