How do I create a JS file in my react app? - reactjs

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();
});
}

Related

How to save SURVEY PDF on the disk

I want to save somes PDF created with 'survey-pdf' on my disk.
Actually, i can send the PDF but i can't save it on my disk.
My final code :
return surveyPDF.save(filename);
Someone can help me ?
Thank you
Can you try
await surveyPDF.save(filename)
?
.save seems to be an asynchronous function that downloads the PDF file.
From the docs
Call save method of surveyPDF object to download file in browser. This is asynchronous method
#2 If the first method doesn't work, you can try this
function savePdfAsString() {
const surveyPDF = new SurveyPDF.SurveyPDF(json);
surveyPDF.data = survey.data;
surveyPDF
.raw("dataurlstring")
.then(function (text) {
//var file = new Blob([text], {type: "application/pdf"});
var a = document.createElement("a");
//a.href = URL.createObjectURL(file);
a.href = text;
a.download = "surveyAsString.pdf";
//document
// .body
// .appendChild(a);
a.click();
});
}
Here you are using the .raw function to transform the PDF into a dataurlstring and then downloading that. Here's the docs for this
*Not tested

how can i add multiple images and preview them using react and express?

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.

Get a .js file dynamically rather than importing them

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);

Download files with AngularJS

I need to allow the user to download an array of bytes I get from a REST api.
The backend api return something like this:
GET /api/files/123
{
filename: 'myfile.pdf',
file: [base64]
}
On my html I have something like this:
<div ng-click="click()">Download</div>
And somewhere in my controller I have:
$scope.click: function (){
$http.get('/api/files/123',{headers:{x-security:'some_sec_token'}})
.then(
function (response){
// do something to return the array of bytes
},
function (error){
console.log(error);
}
);
}
I'm stuck on how to return the array of bytes with the Content-Disposition header using the filename returned by the api.
If you want to create a file using the array of bytes as content then you can use this library:
https://github.com/eligrey/FileSaver.js/blob/master/FileSaver.js
Import that library in you angular project and then try this:
var blob = new Blob(<arrayOfBytes>, {type: <yourFileType>});
saveAs(blob, [nameToSave]);
yourFileType should be something like "image/jpg" or similar depending on your file type
nameTosave should have the file type as well.. example: "myFile.pdf"
Hope it helps.
Cheers

Nodejs module to find files?

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);
});

Resources