I search a module to find files in nodejs.
I would like something like:
var finder = require('finder');
var path = finder.find('/path/to/*.js');
Then path is an array with for example:
/path/to/file.js
/path/to/sub/file.js
...
In addition to #pksunkara answer:
https://github.com/isaacs/node-glob
https://github.com/zzak/gsub
https://github.com/dvv/meta-fs
For simple searches supporting callbacks you can use:
https://github.com/yuanchuan/find
Alternatively, you can use filehound which supports async (callbacks, promises) and sync calls. In addition, you can specify multiple search criteria like file extension, size etc
Example:
const Filehound = require('filehound');
const files = Filehound.create()
.ext('js')
.findSync();
console.log(files) // json files
Repo:
https://github.com/nspragg/filehound
API docs:
https://nspragg.github.io/filehound/
fs-jetpack can do this in a very simple way:
const jetpack = require("fs-jetpack");
// sync way
const files = jetpack.find("my_folder", { matching: "*.js" });
console.log(files);
// or async way
jetpack.findAsync("my_folder", { matching: "*.js" }).then(files => {
console.log(files);
});
Related
I have a silly library that can only load the required meta data from another JS file. That file looks like this
// customStuff.js
__customStuff = [
{.. stuff 1},
{.. stuff 2},
{.. etc}
]
That silly library uses a parameter called custom_stuff_filename which is a string that describes the custom stuff file
{
custom_stuff_file_name: "customStuff.js"
}
customStuff.js sits in a public folder that looks like this myapp/public/silly_library/static/customStuff.js whereas the rest of my source code sits in myapp/src/
As you can see, customStuff.js is static. Stuff inside that file sits there only if I put it.
I don't want it this way. Instead, I want to make an API call in some file in my src so that a __customStuff is a result of that API call.
How do I do that? Is there any way in javascript where I can save data into another javascript file?
Try in this way :-
componentDidMount{
fetch("URL")
.then(response => {
response.blob().then(blob => {
let url = window.URL.createObjectURL(blob);
let a = document.createElement('a');
a.href = url;
a.download = '__customStuff.json';
a.click();
});
}
im trying to add multiple images using react app and send them to backend code to store them in mongodb
here is the code for the backend :
link
and this is the frontend link
so this code works for just one image
i need to be able to add multiple images
Server
Since you are using multer, change the upload.single() function to upload.array().
For example:
app.post("/addItem",
upload.array('product-image', 4), // 'product-image' is field name and 4 is the max number of files allowed
(req, res) => {
console.log(req.files);
// ... rest of the logic
}
)
Check out docs for upload.array()
Client
Change current <input> to allow multiple files:
<input type="file" name="product-image" onChange={this.fileChangeHandler} multiple>
Now save all the images user picked not only the event.target.files[0]:
fileChangeHandler(event) {
let files = event.target.files
this.setState({ selectedFiles: files })
}
Now add them in FormData and upload as usual:
let formData = new FormData()
formData.append("product-image", this.state.selectedFiles)
That's it! Hope it helps.
PS: I don't think files should be added to state. You can simply add them to a class variable. In this answer I explained why and how to do that.
Update:
You need to loop over the files now. Your /addItem endpoint's code will look something like this:
app.post("/addItem", upload.array('product-image', 4), (req, res) => {
console.log(req.files);
let paths = [];
req.files.forEach(file => {
console.log("new file location", file.path)
let extension = file.originalname.split(".").pop()
fs.rename(file.path, file.path + "." + extension, () => {})
paths.push("/" + file.filename + "." + extension);
});
console.log("body", req.body)
let itemToStore = {
paths: paths, // notice this `paths` now, it was `path`
description: req.body.description
}
console.log("we are adding", itemToStore)
itemData.push(itemToStore)
console.log("updated itemData:", itemData)
res.send(JSON.stringify(itemData))
})
I didn't modify your code, just added a loop. Your 'path' of undefined error should go away.
I have recently learned AngularJS. I started a small project. I was able to extract data from a json file. My current task is to be able to extract data from multiple json files. How can I do this?
I made my first json file this way:
$http.get("personel.json")
.then(function(gelen) {
$scope.personeller = gelen.data;
});
I have 9 more json files that I need to take, but I want to see the data of the file I'm calling
$http.get("1.json")
.then(function(veri1) {
$scope.x1 = veri1.data;
});
the other files are named "1.json, 2.json, 3.json ....... 9.json"
How can I change the location of the 1.json in the top code block?I am sorry for my English.The first time I am writing to a foreign forum. Thanks in advance
$scope.getdetail = function(detail) {
$scope.result = detail;
$http.get($scope.result.id + ".json")
.then(function(veri1) {
$scope.x1 = veri1.data;
});
}
I solved my problem this way thanks.
You can wrap the $http call in a function and pass in the filename you wish to retrieve like this:
Edit I modifed the code here adding a promise to handle issues that could arise from asynchronous requests
$scope.getFile = async function(fileName){
return new Promise((res, err) => {
$http.get(fileName).then(function(result){
res(result.data);
})
})
}
$scope.file1 = $scope.getFile("1.json");
$scope.file2 = $scope.getFile("2.json");
$scope.file3 = $scope.getFile("3.json");
$scope.file4 = $scope.getFile("4.json");
$scope.file5 = $scope.getFile("5.json");
$scope.file6 = $scope.getFile("6.json");
$scope.file7 = $scope.getFile("7.json");
$scope.file8 = $scope.getFile("8.json");
$scope.file9 = $scope.getFile("9.json");
If the files are sequential and numeric you could also use this to pull all the data from the file into a single array using a for loop.
$scope.returnedFiles = [];
for(i = 0; i < 9; i++){
$scope.getFile(i + ".json").then(fileData => {
$scope.returnedFiles.push(fileData);
});
}
I have a small app that gives support to 30+ languages. I used react-intl to achieve my task. In react-intl I got to import every locale where every local file is around 7-8kbs, whereas I want to reduce these unnecessary imports and want to import only one file
app.js
import {IntlProvider, addLocaleData} from 'react-intl'
import ca from 'react-intl/locale-data/ca'
import cs from 'react-intl/locale-data/cs'
...
import hu from 'react-intl/locale-data/hu'
import id from 'react-intl/locale-data/id'
import enMessages from '../assets/translations/en.json'
Translations.getLocale('fr').then(function(localeData){
addLocaleData(localeData);
console.log("localeData");
console.log(localeData); //Code instead of array of objects
}, function(status) {
alert('Something went wrong.');
});
Now the ca, cs,hu etc. contain array of objects returned from the respective js files.
I tried using XHR but instead of returning the array of objects, I get the code that is written in the .js file. Is there any way I can dynamically import the js file or if I can get the array of objects from the code returned by XMLHttpRequest.
Translations.js
getLocale: function(lang, successHandler, errorHandler){
var url = 'http://localhost/img/' + lang + '.js';
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('get', url, true);
//xhr.responseType = 'application/javascript';
xhr.onload = function() {
var status = xhr.status;
if (status == 200) {
resolve(xhr.response);
} else {
reject(status);
}
};
xhr.send();
});
//return message;
}
If I understand you correctly, you retrieve the javascript code, which you want retrieve the output from.
One solution is to use eval, although this is generally not considered very secure. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
You can also make the code an automatically executing function that puts the output on a global variable, and access it from there. Append the content of the js file as a script in the head tag, and make the file contain something like.
myGlobalVar = (function() {
return {
key: val
};
})();
I do not know the format of your translate.js files, but you could also consider putting the translations in a json file, if it's a fixed output for each language. Which I think would be the safest solution.
I managed to load the locale files dynamically like this :
Note that my locale string formatting might not be ideal, and ignore the polyfill if you don't plan on supporting old browsers.
import {addLocaleData} from 'react-intl';
const locale = // get this from browser language
// ensure that the polyfill is loaded before calling this
const isUsingIntlPolyfill = Object.prototype.hasOwnProperty.call(window, 'IntlPolyfill');
// eg: turns 'fr-fr' into 'fr-FR' because intl polyfill locale files are formatted like this
const formatLocale = str => `${str.split('-')[0]}${str.split('-')[1] ? `-${str.split('-')[1].toUpperCase()}` : ''}`;
if (isUsingIntlPolyfill) {
const polyfill = document.createElement('script');
// path of the file might differ for your setup
polyfill.setAttribute('src', `/i18n/polyfill/${formatLocale(locale)}.js`);
document.getElementsByTagName('head')[0].appendChild(polyfill);
}
const script = document.createElement('script');
// path of the file might differ for your setup
script.setAttribute('src', `/i18n/${locale.split('-')[0]}.js`);
script.onload = () => {
addLocaleData([...window.ReactIntlLocaleData[locale.substring(0, 2)]]);
// your locale is loaded, do some more stuff from here ...
};
document.getElementsByTagName('head')[0].appendChild(script);
I am using the File() constructor for creating file object for uploading a blob file to the server. The following code works fine for Chrome, but fails for Safari and Internet Explorer.
image_url = new File([blob],file_name,{type: mimeString});
The code is breaking at this line and getting this error in console "FileConstructor is not a constructor" (evaluating 'new File([blob],file_name,{type: mimeString})')
Using the FileReader API is an alternative to this but I am not able to fix this issue.
I Suggest to use the blob api, I've found the same problem and I solved like that:
var html = <svg>whatever on svg </svg>
var fileName = "myfile.svg";
var blob = new Blob([html], {type: 'image/svg'});
blob.lastModifiedDate = new Date();
// var blobAttrs = {type: "image/svg"};
// var file = new File([html], fileName, blobAttrs);
var formData = new FormData();
formData.append("file",blob,fileName);
It is not a "file", but you can use it like it was.
According to web "Can I use" Safari does not support the new File() constructor. See this link http://caniuse.com/#feat=fileapi
So I think you have to either use FileReader or maybe use some of the polyfills listed here https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills
Especially this one could be useful for you https://github.com/mailru/FileAPI (I did not use it myself)
Also have a look at this SO answer What to use instead of FileReader for Safari?
If you can use ES6 classes:
class CustomFile extends Blob
{
constructor(blobParts, filename, options) {
super(blobParts, options);
this.name = filename || "";
if(options) {
this.lastModified = options.lastModified;
}
}
lastModified = 0;
name = "";
}
const blob = new Blob();
const fileObject = new CustomFile([blob],"myfile");
console.log(fileObject);
There is a File ponyfill on npm which works with modern module imports. This makes usage simple but you do need to import it in every module where you use new File().
import File from '#tanker/file-ponyfill';
const myFile = new File(['somefiledata'], 'example.txt', { type: 'text/plain'});