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