Read uploaded JSON file in Angular - javascript

I am using the <p-fileUpload> from PrimeNG to upload a json file in my web-app. I want to read the json file, in the front-end, and change some values of a data table.
However, I have no idea how to parse the uploaded file as a json to a typescript object. Any ideas?
In the HTML file:
<p-fileUpload #ratingsUpload mode="basic" name="demo[]"
url="" accept=".json"
styleClass="p-button-raised"
[auto]="true" chooseLabel="Upload ratings"
(onUpload)="onRatingsUpload($event)"></p-fileUpload>
In the typescript file:
onRatingsUpload(event: any) {
console.log(event.files)
// TODO:
// data = JSON(event.files);
}
Edit: I can't get the event to fire. onRatingsUpload does not seem to be called...

You have to use FileReader:
const reader = new FileReader();
reader.onload = (event) => {
try {
var obj = JSON.parse((event.target.result) as string);
console.log('my json:', obj);
} catch (error) {
console.error(error);
}
};
reader.readAsText(file);

//You need to use FileReader
onFileChanged(event) {
this.selectedFile = event.target.files[0];
const fileReader = new FileReader();
fileReader.readAsText(this.selectedFile, "UTF-8");
fileReader.onload = () => {
console.log(JSON.parse(fileReader.result));
}
fileReader.onerror = (error) => {
console.log(error);
}
}

Related

convert file to base64 in angular

i am new to angular and i want to convert files into base64 string. i try this and it gives base64 string but when i try to decode it using online tool it did not give correct result can anyone help me thank you.
can we convert pdf and word file into base64 or just images. with my code i successfully converted images but not any other file
my html code:
<input type="file" (change)="base($event)">
and my ts code:
base(event: { target: { files: any[]; }; }) {
const file = event.target.files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
console.log(reader.result);
};
}
Your code works fine. Are you sure you are correctly getting the file object?
Below is the stackblitz demo of the same.
Also, it better to use promise while reading files. You can use below function to read a file. It takes file as input and resolves to base64 string.
private readBase64(file): Promise<any> {
const reader = new FileReader();
const future = new Promise((resolve, reject) => {
reader.addEventListener('load', function () {
resolve(reader.result);
}, false);
reader.addEventListener('error', function (event) {
reject(event);
}, false);
reader.readAsDataURL(file);
});
return future;
}
Call this function as below -
this.readBase64(file)
.then((data) => {
// your code
});

Reactjs Input Upload doesn't return local URL

I have a problem when trying to display image preview before upload it to server. I 'm using reactjs.
My problem is when I try to upload an image I got the file data but when I'm using reader, it doesn't return local URL and just show undefined
this is the topic that I tried to follow get-image-preview-before-uploading-in-react
but when I try to check my image local url it return undefined
this is what I import in my file:
import React, {Component} from "react";
import { MDBContainer, MDBRow, MDBCol, MDBBtn, MDBIcon, MDBInput, MDBDropdown, MDBDropdownToggle, MDBDropdownMenu, MDBDropdownItem } from 'mdbreact';
this is my js:
<p className="text-upload">Front Desain</p>
<input ref="file" type="file" name="front Design" onChange={this.frontDesign}/>
this is my method or function:
frontDesign = (e) =>{
var file = this.refs.file.files[0];
var reader = new FileReader();
var url = reader.readAsDataURL(file);
reader.onloadend = function (e) {
this.setState({
form:{
frontDesign: [reader.result]
}
})
}.bind(this);
console.log("Check Data : ", file)
console.log("Check URL : ", url)
}
and this is my state:
state ={
form:{
frontDesign: [],
}
}
this is my console:
This my codesandbox:
https://codesandbox.io/s/tender-mclaren-zb1l7?fontsize=14
can someone help me to solve this?
From the mozilla website it seams you need to add a load event listener to your reader. This sample code is not supported in some versions of IE.
...
reader.addEventListener("load", () => {
this.setState(state => ({
...state,
form:{
frontDesign: [reader.result]
}
}))
const url = reader.result;
console.log(url);
}, false);
...
Working condeSanbox here: https://codesandbox.io/s/affectionate-lamport-dnbij
Do not need use ref here. Try to code below
frontDesign = (e) => {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = (e) => {
//Image URL e.target.result
this.setState({
form:{
frontDesign: [e.target.result]
}
})
}
reader.readAsDataURL(file);
}

Write file to disk from blob in electron application

I am creating an Electron Application in which I am recording data from webcam and desktop, at the end of the recording session, I want to save the data to a file in the background. I do not know how to write the data from a blob to a file directly. Any suggestions?
Below is my current handling for MediaRecord Stop event.
this.mediaRecorder.onstop = (e) => {
var blob = new Blob(this.chunks,
{ 'type' : 'video/mp4; codecs=H.264' });
var fs = require('fs');
var fr = new FileReader();
var data = null;
fr.onload = () => {
data = fr.result;
fs.writeFile("test.mp4", data, err => {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
};
fr.readAsArrayBuffer(blob);
}
You can do it using FileReader and Buffer.
In the renderer process, send the event to the main process to save the file with the buffer:
function saveBlob(blob) {
let reader = new FileReader()
reader.onload = function() {
if (reader.readyState == 2) {
var buffer = new Buffer(reader.result)
ipcRenderer.send(SAVE_FILE, fileName, buffer)
console.log(`Saving ${JSON.stringify({ fileName, size: blob.size })}`)
}
}
reader.readAsArrayBuffer(blob)
}
Get back the confirmation:
ipcRenderer.on(SAVED_FILE, (event, path) => {
console.log("Saved file " + path)
})
(SAVE_FILE and SAVED_FILE are static strings containing event name)
and in the main process:
ipcMain.on(SAVE_FILE, (event, path, buffer) => {
outputFile(path, buffer, err => {
if (err) {
event.sender.send(ERROR, err.message)
} else {
event.sender.send(SAVED_FILE, path)
}
})
})
outputFile is from 'fs-extra'
Handling node operations in main process is preferred. See Electron Security suggestions.
If you do want to not use main process, you can use 'electron-remote' to create background processes to write the file. Additionally, you can invoke ffmpeg in the background process to compress/encode the file into different format.

PSD.js in react error fs.readFileSync is not a function

I have a reactjs project using psd.js and on my dropzone config like this
accept: function(file, done){
const reader = new FileReader();
reader.onload = handleReaderLoad;
reader.readAsDataURL(file);
function handleReaderLoad(evt) {
console.log(evt.target.result);
let psdFile = PSD.fromFile(evt.target.result);
psdFile.parse();
console.log(psdFile);
}
done();
},
The error is:
Uncaught TypeError: fs.readFileSync is not a function
at Function.fromFile (init.coffee:6)
at FileReader.handleReaderLoad (index.js?03a7:153)
in my webpack config i inlclude :
node: {
fs: 'empty'
},
Because if I don't include it, the error is: not found fs module
Please help.
You should use PSD.fromEvent(evt), not PSD.fromFile.
The former reads the blob from a file input, while the latter tries to hit the filesystem which is obviously absent in the browser context.
So I guess your code should look like this (but I'm not quite sure)
accept: function(file, done){
const reader = new FileReader();
reader.onload = handleReaderLoad;
reader.readAsDataURL(file);
function handleReaderLoad(evt) {
PSD.fromEvent(evt).then(function (psd) {
// here you can access the parsed file as psd
console.log(psd.tree().export());
done();
});
}
},

How to upload files from ReactJS to Express endpoint

In the application I'm currently working on, there are a couple of file forms that are submitted via superagent to an Express API endpoint. For example, image data is posted like so:
handleSubmit: function(evt) {
var imageData = new FormData();
if ( this.state.image ) {
imageData.append('image', this.state.image);
AwsAPI.uploadImage(imageData, 'user', user.id).then(function(uploadedImage) {
console.log('image uploaded:', uploadedImage);
}).catch(function(err) {
this.setState({ error: err });
}.bind(this));
}
}
and this.state.image is set like this from a file input:
updateImage: function(evt) {
this.setState({
image: evt.target.files[0]
}, function() {
console.log('image:', this.state.image);
});
},
AWSAPI.uploadImage looks like this:
uploadImage: function(imageData, type, id) {
var deferred = when.defer();
request.put(APIUtils.API_ROOT + 'upload/' + type + '/' + id)
.type('form')
.send(imageData)
.end(function(res) {
if ( !res.ok ) {
deferred.reject(res.text);
} else {
deferred.resolve(APIUtils.normalizeResponse(res));
}
});
return deferred.promise;
}
And lastly, the file receiving endpoint looks like this:
exports.upload = function(req, res) {
req.pipe(req.busboy);
req.busboy.on('file', function(fieldname, file) {
console.log('file:', fieldname, file);
res.status(200).send('Got a file!');
});
};
Currently, the receiving endpoint's on('file') function never gets called and so nothing happens. Previously, I've tried similar approaches with multer instead of Busboy with no more success (req.body contained the decoded image file, req.files was empty).
Am I missing something here? What is the best approach to upload files from a (ReactJS) Javascript app to an Express API endpoint?
I think superAgent is setting the wrong content-type of application/x-form-www-encoded instead of multipart/form-data you can fix this by using the attach method like so:
request.put(APIUtils.API_ROOT + 'upload/' + type + '/' + id)
.attach("image-file", this.state.image, this.state.image.name)
.end(function(res){
console.log(res);
});
for more information about the attach method, read the documentation here: http://visionmedia.github.io/superagent/#multipart-requests
since this involves a nodejs server script I decided to make a GitHub repo instead of a fiddle: https://github.com/furqanZafar/reactjs-image-upload
From experience, uploading a file using ajax works when you use FormData, however the file must be the only form field / data. If you try and combine it with other data (like username, password or pretty much anything at all) it does not work. (Possibly there are work arounds to get around that issue, but I am not aware of any)
If you need to send the username/password you should be sending those as headers if you can instead.
Another approach I took was first do the user registration with the normal data, then on success I upload the file with the FormData separately as an update.
The react file upload iamges component:
class ImageUpload extends React.Component {
constructor(props) {
super(props);
this.state = {file: '',imagePreviewUrl: ''};
}
_handleSubmit(e) {
e.preventDefault();
// this.uploadImage()
// TODO: do something with -> this.state.file
console.log('handle uploading-', this.state.file); }
_handleImageChange(e) {
e.preventDefault();
let reader = new FileReader();
let file = e.target.files[0];
reader.onloadend = () => {
this.setState({
file: file,
imagePreviewUrl: reader.result
});
}
reader.readAsDataURL(file) }
// XHR/Ajax file upload uploadImage(imageFile) {
return new Promise((resolve, reject) => {
let imageFormData = new FormData();
imageFormData.append('imageFile', imageFile);
var xhr = new XMLHttpRequest();
xhr.open('post', '/upload', true);
xhr.onload = function () {
if (this.status == 200) {
resolve(this.response);
} else {
reject(this.statusText);
}
};
xhr.send(imageFormData);
}); }
render() {
let {imagePreviewUrl} = this.state;
let $imagePreview = null;
if (imagePreviewUrl) {
$imagePreview = (<img src={imagePreviewUrl} />);
} else {
$imagePreview = (<div className="previewText">Please select an Image for Preview</div>);
}
return (
<div className="previewComponent">
<form onSubmit={(e)=>this._handleSubmit(e)}>
<input className="fileInput" type="file" onChange={(e)=>this._handleImageChange(e)} />
<button className="submitButton" type="submit" onClick={(e)=>this._handleSubmit(e)}>Upload Image</button>
</form>
<div className="imgPreview">
{$imagePreview}
</div>
</div>
) } } React.render(<ImageUpload/>, document.getElementById("mainApp"));
The Server Side Image Save and Copy:
Along with express You needed to npm install 'multiparty'. This example uses multiparty to parse the form data and extract the image file information. Then 'fs' to copy the temporarily upload image to a more permanent location.
let multiparty = require('multiparty');
let fs = require('fs');
function saveImage(req, res) {
let form = new multiparty.Form();
form.parse(req, (err, fields, files) => {
let {path: tempPath, originalFilename} = files.imageFile[0];
let newPath = "./images/" + originalFilename;
fs.readFile(tempPath, (err, data) => {
// make copy of image to new location
fs.writeFile(newPath, data, (err) => {
// delete temp image
fs.unlink(tempPath, () => {
res.send("File uploaded to: " + newPath);
});
});
});
})
}

Categories