I'm trying to get the current clicked folder from an array of my app's root folder and read it with readdirSync and I can't find anything helpful.
So far, what I got is only the index number on click, but I can't read it because it is not a string.
Here is what I have now :
const fs = require('fs');
$('li').click(function() {
file = $('li').index(this);
fs.readdirSync(file);
console.log(file);
})
My app
So, to read my root folder I have : let files = fs.readdirSync('.') and a forEach function. I want to click on "js" folder for example, and display what is inside it but I don't know how.
I'm new to electron and node.js :)
Thanks!
This bit of code will be used in the code that follows after:
const fileSystem = require("fs");
const getDirectoryContents = path => fileSystem.readdirSync(path);
Assuming your ul has an id called main, this is what I'd do:
$("#main li").on("click", function clickHandler() {
const $clickedElement = $(this);
const elementName = $clickedElement.text(); // gets the text that was clicked
const fsEntry = fileSystem.statSync(elementName);
if (fsEntry.isDirectory()) { // retrieve the contents only if the clicked text represents a folder
const files = ['<ul>'].concat(
getDirectoryContents(elementName).map(entryName => `<li>${entryName}</li>`),
'</ul>'
).join('');
$clickedElement.append(files); // not exactly the best way to do it, but does the job
} else {
// do something if the entry is a file
}
});
Hope this helps.
Related
Is there any clean way to check if a path is a file or directory?
Currently I am using this:
exports.isDirectory = (dirPath) => {
return fs.lstatSync(dirPath).isDirectory()
}
But my problem here is that if dirPath does not exist yet, then lstatSync gives out an error.
Then I also tried:
exports.getFileName = (filePath) => {
return filePath.split(/[\\\/]/).pop()
}
exports.isDirectory = (dirPath) => {
return exports.getFileName(dirPath) === ''
}
And call:
const home = require('os').homedir()
const sampleLoc = path.join(home, '/.folder/another'))
isDirectory(sampleLoc)
But it only basically thinks another is the filename and returns false on isDirectory.
Can't really check for the presence of . (like an extension of a file name) since my folders can have dots anywhere on its name.
How can I check if the given path is for a file or directory? (considering it does not exist yet at the point of checking)?
Help!
So everyone is familiar with serving static files from a hard-coded path such as /public. How do I do that but serve files from a path provided as input from the user?
Use case: This is a local server and so after running the server, the user selects which folder to serve so that it can be available across the local network for access. I'm looking to create a video streaming API which will play videos served on the path selected by the user.
Currently, I list the items in the path like so:
const Promise = require('bluebird');
const path = require('path')
const fs = Promise.promisifyAll(require('fs'));
async listDir(dir) {
const list = [];
const dirItems = await fs.readdirAsync(dir); // get all items in the directory
for (const item of dirItems) {
const absPath = path.join(dir, item);
const stat = await fs.lstatAsync(absPath);
const isFile = stat.isFile(); // check if item is a file
list.push({ name: item, isFile }); // return item name and isFile boolean
}
return list;
}
Do I then just do pattern-matching in another route to return whichever file is asked for inside the dir?
Am I going about this the right way? Any suggestion/answer is appreciated.
I am attempting to do a file search based off array of file names and root directory. I found some file search snips online that seem to work when I am finding just 1 single file, but it will not work when there is more than 1 file specified. Below is the snippet:
const fs = require('fs');
const path = require('path');
var dir = '<SOME ROOT DIRECTORY>';
var file = 'Hello_World.txt'
var fileArr = ['Hello_World.txt', 'Hello_World2.txt', 'Hello_World3.txt'];
const findFile = function (dir, pattern) {
var results = [];
fs.readdirSync(dir).forEach(function (dirInner) {
dirInner = path.resolve(dir, dirInner);
var stat = fs.statSync(dirInner);
if (stat.isDirectory()) {
results = results.concat(findFile(dirInner, pattern));
}
if (stat.isFile() && dirInner.endsWith(pattern)) {
results.push(dirInner);
}
});
return results;
};
console.log(findFile(dir, file));
Any thoughts on how I can get this working with an array rather than just a single file string?
Doing the following seems to be working, but didn't know if there were other ways to do this which may be simpler:
newFileArr = [];
fileArr.forEach((file => {
//findFile(dir, file).toString();
console.log(findFile(dir, file).toString());
}));
The only thing that needs to change is the condition to determine if an individual filepath meets the search criteria. In the code you've posted, it looks like dirInner.endsWith(pattern), which says "does the filepath end with the given pattern?"
We want to change that to say "does the filepath end with any of the given patterns?" And closer to how the code will look, we can rephrase that as "Can we find a given pattern such that the filepath ends with that pattern?"
Let's rename pattern to patterns. Then we can simple replace dirInner.endsWith(patterns) with patterns.some(pattern => dirInner.endsWith(pattern))
I'm in another pickle I've realized over the past week that my images are not loading due to the fact the links have expired so I wanna find out how to go about using a file directory in the code.
Here's what I've tried:
});
client.on('message', message => {
if (message.content.startsWith('L!hug')) {
var fs = require('fs');
var files = fs.readdirSync('C:\Users\nevbw\Desktop\games\FBIBot\images\hugs')
/* now files is an Array of the name of the files in the folder and you can pick a random name inside of that array */
let chosenFile = files[Math.floor(Math.random() * files.length)]
}
});
and
});
client.on('message', message => {
if (message.content.startsWith('L!hug')) {
const path = 'C:\Users\nevbw\Desktop\games\FBIBot\images\hugs';
const fs = require('fs');
fs.readdirSync(path).forEach(file => {
ranfile = Math.floor(Math.random() * file.length);
message.channel.sendFile(ranfile);
})
}
});
found out through searching and searching but found a answer the modified it to this, i hope people use this in future reference!
const num = (Math.floor(Math.random()* 5)+1).toString(); message.channel.send({files: [`./slap/slap${num}.gif`]})
Using fs.readdirSync('./images/') instead of fs.readFileSync('./images/') works easier, but then you will have to create the folder inside of VSC and put the images in the folder, you can also drag and drop the images into the solution and use:
var files = fs.readdirSync(`./images/`).filter(file => file.endsWith('.png'))
so that when it looks for an image, it doesn't select anything else. hope it helps for some people.
Happy to help.
You're using FS the wrong way. This Is What It Should Look Like :D Also Here Is Some Documentation on It ( https://nodejs.org/dist/latest-v13.x/docs/api/fs.html ).
-- Code --
Also Just As A Tip! I See You Are Using Full Directories, That's Quite Innificeng (E.g if You Change Your Username, Drive ID, etc.) so in fs provided the image is in the same folder you can just do ./(ImageName), or if it is in the same folder but under another say /FBIBot/Images you can do ./Images/(ImageName). ^^
--
What The Error Was: (I Unfortunately Cannot Test it But I Am Like 99% Sure).
You Were Using fs.readdirSync(path).forEach(file => { When You Were Meant To Be Using fs.readfilesync(path).forEach(file => {.
-- First Code --
});
client.on('message', message => {
if (message.content.startsWith('L!hug')) {
var fs = require('fs');
var files = fs.readfileSync('C:\Users\nevbw\Desktop\games\FBIBot\images\hugs')
/* now files is an Array of the name of the files in the folder and you can pick a random name inside of that array */
let chosenFile = files[Math.floor(Math.random() * files.length)]
}
});
-- Second Code --
});
client.on('message', message => {
if (message.content.startsWith('L!hug')) {
var fs = require('fs');
var files = fs.readFileSync('C:\Users\nevbw\Desktop\games\FBIBot\images\hugs')
/* now files is an Array of the name of the files in the folder and you can pick a random name inside of that array */
let chosenFile = files[Math.floor(Math.random() * files.length)]
}
});
^^
I tagged watchman as it MIGHT be the solution I'm looking for, but I don't quite know how to use it in this way!
I have a directory
/imgs
/icons
/bird.png
/cat.png
/dog.png
/pig.png
and I have a file
/imgs/index.js
My index.js is responsible for importing all of the images and then exporting a single object for the rest of my project to use.
const bird = require('./icons/bird.png');
const cat = require('./icons/cat.png');
const dog = require('./icons/dog.png');
const pig = require('./icons/pig.png');
const Icons = { bird, cat, dog, pig };
export default Icons;
What I want to do is watch my imgs folder for new additions, and automatically update my index.js to import these new files and add them to my object. I need to import them with Common.js and export them with ES6.
Does anyone know a good solution to this problem?
A potential solution is to write a JavaScript script that generates your index.js like so:
'use strict';
const fs = require('fs');
const DIR = __dirname + '/imgs/icons';
const output = __dirname + '/imgs/index.js';
return fs.readdir(DIR, (err, files) => {
let result = '';
let references = [];
files.forEach(item => {
// assuming item has the format animal.png
let newReference = item.split('.')[0];
references.push(newReference);
result += `const ${newReference} = require('./icons/${item}');\n`;
});
result += `\nconst Icons = { ${references} };\n\nexport default Icons;`;
fs.writeFile(output, result, err => {
if (err) throw err;
console.log(output + ' updated');
});
});
Place that file (let's call it watcher.js for this purpose) in imgs's parent directory and make watchman run it whenever changes in your icons directory are detected:
watchman imgs/icons "node watcher.js"
Notice that if a new file gets put into the watched directory, the index.js-creating script will not re-run. Only if it gets altered again (even if just gets saved again with the same data), the index.js will reflect that change.
You can simply test that by running touch imgs/icons/crabigator.png twice and look at the watchman log and/or content of index.js.