How to save a JSON file using Blob in JS without HTML - javascript

I just want to store my json data in a file in a particular directory using JS. I can not see the created file using the following code.
var jsonse = JSON.stringify(submitted);
var blob = new Blob([jsonse], {type: "application/json"});
var file = new File([blob], "" + workerID + ".json")
JS Documentation Link would also suffice.

Assuming you're not using a web browser which cannot write to your file system for, hopefully obvious (another question), security reasons.
You can redirect output from your script to a file.
node yourfile.js > output_file.json
Or you can use the fs module.
Writing files in Node.js
// note jsonse is the json blob
var fs = require('fs');
fs.writeFile("/tmp/test", jsonse, function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});

Related

Extract a non ZIP file to files on disk?

I got a App File which is structured like a zip file.
Now I would like to extract all of the files in the app file.
I tried to convert the app to a zip file in the code (just copy and paste as zip file), but then it's a "SFX ZIP Archive", which most of the unzipper in node.js can't read.
For example AdmZip (error message):
rejected promise not handled within 1 second: Error: Invalid CEN
header (bad signature)
var AdmZip = require('adm-zip');
var admZip2 = new AdmZip("C:\\temp\\Test\\Microsoft_System.zip");
admZip2.extractAllTo("C:\\temp\\Test\\System", true)
So now i don't know how to deal with it, because I need to extract the files with all subfolder/subfiles to a specific folder on the computer.
How would you do this?
You can download the .app file here:
https://drive.google.com/file/d/1i7v_SsRwJdykhxu_rJzRCAOmam5dAt-9/view?usp=sharing
If you open it, you should see something like this:
Thanks for your help :)
EDIT:
I'm already using JSZip for resaving the zip file as a normal ZIP Archive. But this is a extra step which costs some time.
Maybe someone knows how to extract files to a path with JSZip :)
EDIT 2:
Just for you information: It's a VS Code Extension Project
EDIT 3:
I got something which worked for me.
For my solution I did it with Workers (Because parallel)
var zip = new JSZip();
zip.loadAsync(data).then(async function (contents) {
zip.remove('SymbolReference.json');
zip.remove('[Content_Types].xml');
zip.remove('MediaIdListing.xml');
zip.remove('navigation.xml');
zip.remove('NavxManifest.xml');
zip.remove('Translations');
zip.remove('layout');
zip.remove('ProfileSymbolReferences');
zip.remove('addin');
zip.remove('logo');
//workerdata.files = Object.keys(contents.files)
//so you loop through contents.files and foreach file you get the dirname
//then check if the dir exists (create if not)
//after this you create the file with its content
//you have to rewrite some code to fit your code, because this whole code are
//from 2 files, hope it helps someone :)
Object.keys(workerData.files.slice(workerData.startIndex, workerData.endIndex)).forEach(function (filename, index) {
workerData.zip.file(filename).async('nodebuffer').then(async function (content) {
var destPath = path.join(workerData.baseAppFolderApp, filename);
var dirname = path.dirname(destPath);
// Create Directory if is doesn't exists
await createOnNotExist(dirname);
files[index] = false;
fs.writeFile(destPath, content, async function (err) {
// This is code for my logic
files[index] = true;
if (!files.includes(false)) {
parentPort.postMessage(workerData);
};
});
});
});
jsZip is A library for creating, reading and editing .zip files with JavaScript, with a lovely and simple API.
link (https://www.npmjs.com/package/jszip)
example (extraction)
var JSZip = require('JSZip');
fs.readFile(filePath, function(err, data) {
if (!err) {
var zip = new JSZip();
zip.loadAsync(data).then(function(contents) {
Object.keys(contents.files).forEach(function(filename) {
zip.file(filename).async('nodebuffer').then(function(content) {
var dest = path + filename;
fs.writeFileSync(dest, content);
});
});
});
}
});
The file is a valid zip file appended to some sort of executable.
The easiest way is to extract it calling an unzipper such as unzipada.exe - free, open-source software available here. Pre-built Windows executables available in the Files section.

MS Graph API file replace SharePoint ReactJS 404 item not found or stream issue

I am trying to use the MS Graph API and ReactJS to download a file from SharePoint and then replace the file. I have managed the download part after using the #microsoft.graph.downloadUrl value. Here is the code that gets me the XML document from SharePoint.
export async function getDriveFileList(accessToken,siteId,driveId,fileName) {
const client = getAuthenticatedClient(accessToken);
//https://graph.microsoft.com/v1.0/sites/{site-id}/drives/{drive-id}/root:/{item-path}
const files = await client
.api('/sites/' + siteId + '/drives/' + driveId + '/root:/' + fileName)
.select('id,name,webUrl,content.downloadUrl')
.orderby('name')
.get();
//console.log(files['#microsoft.graph.downloadUrl']);
return files;
}
When attempting to upload the same file back up I get a 404 itemNotFounderror return. Because this user was able to get it to work I think I have the MS Graph API correct, although I am not sure I'm translating correctly to ReactJS syntax. Even though the error message says item not found I think MS Graph might actually be upset with how I'm sending the XML file back. The Microsoft documentation for updating an existing file state the contents of the file in a stream should be returned. Since I've loaded the XML file into the state I'm not entirely sure how to send it back. The closest match I found involved converting a PDF to a blob so I tried that.
export async function putDriveFile(accessToken,siteId,itemId,xmldoc) {
const client = getAuthenticatedClient(accessToken);
// /sites/{site-id}/drive/items/{item-id}/content
let url = '/sites/' + siteId + '/drive/items/' + itemId + '/content';
var convertedFile = null;
try{
convertedFile = new Blob(
[xmldoc],
{type: 'text/xml'});
}
catch(err) {
console.log(err);
}
const file = await client
.api(url)
.put(convertedFile);
console.log(file);
return file;
}
I'm pretty sure it's the way I'm sending the file back but the Graph API has some bugs so I can't entirely be sure. I was convinced I was getting the correct ID of the drive item but I've seen where the site ID syntax can be different with the Graph API so maybe it is the item ID.
The correct syntax for putting an (existing) file into a document library in SharePoint is actually PUT /sites/{site-id}/drive/items/{parent-id}:/{filename}:/content I also found this code below worked for taking the XML document and converting into a blob that could be uploaded
var xmlText = new XMLSerializer().serializeToString(this.state.xmlDoc);
var blob = new Blob([xmlText], { type: "text/xml"});
var file = new File([blob], this.props.location.state.fileName, {type: "text/xml",});
var graphReturn = await putDriveFile(accessToken, this.props.location.state.driveId, this.state.fileId,file);

Case insensitive for loading XML file name using JavaScript

Hi all I am loading XML file with file name 'Attachments.xml' using the following code:
var attachmentsXml = XmlBuddy.load(file, 'Attachments.xml');
Now if I want to load the xml-file with file name as 'attachments.xml' I am unable to load so can anyone suggest me how to do.
Most likely you are using node.js so you can use the xml2json
fs = require('fs');
var parser = require('xml2json');
fs.readFile( './Attachments.xml', function(err, data) {
var json = parser.toJson(data);
console.log("to json ->", json);
});

fs.write json file to capture and save streaming json file

I want json stream stored in text file. When running the node server, the json file isn't appended to the json.txt file. What am I missing? Am new to to node, so be gentle..
Here is a code chunk I expect to capture the json content:
var fs = require('fs');
fs.writeFile("json.txt",{encoding:"utf8"}, function(err) {
if(err) {
console.log(err);
} else {
console.log("The file was saved!");
}
});
The issue is you aren't using the correct parameters. When calling fs.writeFile it expects a string for the filename, a buffer or string for the content, an object for the options and a callback function. What it looks like you're doing is sending the options as the second parameter when it expects a buffer or a string. Correction below;
var fs = require('fs');
fs.writeFile("json.txt", JSON.stringify({some: object}), {encoding:"utf8"}, function(err) {
if(err) {
console.log(err);
} else {
console.log("The file was saved!");
}
});
You can replace the JSON.stringify part with some plain text if you wanted to, but you specified JSON in your question so I assumed you wanted to store some object in a file
Source (NodeJS documentation)
EDIT:
The links to other questions in the comments may be more relevant if you want to add new lines to the end of the file and not completely overwrite the old one. However I made the assumption that fs.writeFile was the intended function. If that wasn't the intention, those other questions will help a lot more
UPDATE:
It seems the issue was the fact that the body wasn't being parsed, so when the POST request was going through, Node didn't have the request body. To alleviate this, during the express configuration, the following code is needed:
var bodyParser = require('body-parser');
app.use(bodyParser.json());
Uses the npm module body-parser. This will convert the JSON body to a JavaScript object, and it is accessible via req.body.

Zip pdf files from url

I'm trying to zip multiple pdf files from existing links using archiver npm module. I am able to zip multiple files from memory or local to my machine, but it doesn't work when I pass in urls in fs.createReadStream().
fs.createReadStream() tells me that all I need to do is pass in the path of the file that I want to stream the data from. I know I am doing something awfully wrong, can't get my head around what exactly it is.
var archiver = require('archiver');
var archive = archiver('zip');
res.set('Content-Type', 'application/zip');
res.set('Content-Disposition', 'attachment; filename=123.zip');
archive.pipe(res);
archive
.append(fs.createReadStream('https://URL-1-XXX.pdf'), { name: 'file1.pdf' });
.append(fs.createReadStream('https://URL-1-XXX.pdf'), { name: 'file2.pdf' });
archive.finalize(function(err, bytes) {
if (err)
throw err;
console.log('done: ', bytes);
});
fs.createReadStream is used to read files stored on disk, not make HTTPS requests. I'd advise you to read the API docs a little further and look into the https module.
Try this instead:
var request = require('request');
archive
.append(request.get('https://URL-1-XXX.pdf'), { name: 'file1.pdf' });
.append(request.get('https://URL-1-XXX.pdf'), { name: 'file2.pdf' });

Categories