Can we render InputStream from Spring Boot Backend on React Frontend? - reactjs

I have a virtual file system in my java spring boot backend that converts any file into an InputStream, I am sending this InputStream using REST to my React frontend. Is there anyway I can accordingly render this InputStream on the frontend?
This InputStream may be an text file, image file, xml file, etc.

Sure. I've an example using axios.
const readFile = async (filename: string) => {
try {
// fetch your file
const response = await axios.get(`/api/file/${filename}`, {
responseType: "arraybuffer",
});
// read your response into a blob
const file = new Blob([response.data], {
type: "text/plain",
});
// read your blob as text
const reader = new FileReader();
reader.onload = () => {
alert(reader.result);
};
reader.readAsText(file);
} catch (e) {
// error handling
console.error(e);
}
};
If you have an image you would want to use URL.createObjectURL:
const file = new Blob([response.data], {
type: "image/png",
});
const objectURL = URL.createObjectURL(file);
myImage.src = objectURL;

Related

React FileReader readAsDataURL not working: URL can't be decoded in flask backend as format == None

I'm working on a basic React web app where user can upload images, and images are send to the flask backend to be processed. I'm using FileReader class to convert the uploaded images through into URLs, and then send them to the backend, where I need to decode the URLs then converted it into an np.array for the processing.
The issue is, when I try to decode the image with image_data = base64.b64decode(image_url) and get the image with Image.open(io.BytesIO(image_data)), somehow it won't recognize the url as an image? Basically I got this error:
raise UnidentifiedImageError(
PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x2e8950b30>
I checked the image format with image_format = imghdr.what(io.BytesIO(image_data)), and the image_format equals to None. Do I need to specify the format when encoding the image?
Here's my code:
in React App():
handleImageUploadSelect = (event) => {
let imageURLs = [];
const files = event.target.files;
for ( let i = 0; i < files.length; i++ ) {
// load file object
const file = files[i]
// file reader
const reader = new FileReader();
reader.onload = (event) => {
const dataURL = event.target.result;
// add dataURL to the state variable
imageURLs[i] = dataURL;
}
reader.readAsDataURL(file);
}
this.state.uploadImageURLs = imageURLs;
}
handleImageUpload = event => {
event.preventDefault();
// send uploadImageURLs back to flask server
const data = { images: this.state.uploadImageURLs };
console.log(data)
fetch('http://127.0.0.1:5000/add_images', {
method:'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
},
})
.then((response) => response.json())
.then((data) => {
// response data
console.log(data)
})
.catch((error) => {
console.error(error);
});
}
And in flask server file:
#main.route('/add_images', methods=['POST'])
#cross_origin()
def add_images():
data = request.get_json()
for imageURL in data['images']:
image_data = base64.b64decode(imageURL)
image = Image.open(io.BytesIO(image_data))
image_array = np.array(image)
# processing ...
return jsonify({"condition": "image received"})
Please Help! Thanks!

Pass Files to Node Server

Im having this function in my react app, what is does is sending a file to the server and the server save it to the declared dir.
const handleUploadfile = (event) => {
event.preventDefault();
const data = new FormData();
data.append('file',file );
fetch("http://localhost:4000/upload", {
method: 'POST',
body: data
}).then((response) => console.log(response))
}
heres the code in the node server handling the request above
app.post("/upload", (req, res) => {
const newpath = "./files/";
const file = req.files.file;
const filename = file.name;
file.mv(`${newpath}${filename}`, (err) => {
if (err) {
res.status(500).send({ message: "File upload failed", code: 200 });
}
res.status(200).send({ message: "File Uploaded", code: 200 });
});
});
The upload is working well, but what i want to know is, am i able to include some data like a string directory for each uploaded file something like that.
BTW im using express-uploadfile middleware so i can access the files.
If you want to upload another filed in your request you simply need to call append on your FormData object.
const data = new FormData();
data.append('file',file );
data.append('string','some string');
Then read it on the server
const string = req.body.string;

Convert blob url to file or Base64 to upload to cloudinary

I have converted the file to blob url by creating a canvas,
Now I want to convert blob url to either file type or base64 type to upload to cloudinary.
But it seems very challenging to me, as none of them are working.
The below code is to convert the images to the blob url, acutally I am square cropping them
CanvasUtils.js
export async function getCroppedImg(
imageSrc,
pixelCrop,
...
) {
...
return new Promise((resolve) => {
canvas.toBlob((file) => {
resolve(URL.createObjectURL(file));
}, "image/png");
});
My try's:
Converting blob url to blob oject and then to file format
for (let i = 0; i < imageUrls.length; i++) {
console.log("This is from within the loop: imageURL", imageUrls[i]);
let blob = new Blob([imageUrls[i]], { type: "image/jpg" });
console.log("Blob is ", blob);
var myFile = blobToFile(blob, "myimage.jpg");
// uploading code goes here [find the code below]
}
Converting blob url to blob oject and then to base64
let reader = new FileReader();
reader.readAsDataURL(blob); // converts the blob to base64 and calls onload
reader.onloadend = async function () {
let myFile = reader.result; // data url
// uploading code goes here [find the code below]
}
The uploading code to save it in cloudinary goes like.
console.log(typeof myFile);
data.append("file", myFile);
data.append("upload_preset", "myPreset");
const res = await fetch(
"https://api.cloudinary.com/v1_1/dpurb6xes/image/upload",
{
method: "Post",
body: data,
}
);
const response = await res.json();
console.log(response.secure_url);
Output for try 1 goes like:
Output for try 2 goes like:
What is the good request then ??
In both the cases you are actually converting the imageUrl into blob.
For some reason it doesn't work.
Instead converting the imageUrl directly to the blob worked for me.
The code goes like:
const getBase64FromUrl = async (url) => {
const data = await fetch(url);
const blob = await data.blob();
return new Promise((resolve) => {
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = () => {
const base64data = reader.result;
resolve(base64data)
};
});
};
And then use the function like this.
const myImage = await getBase64FromUrl(imageUrls[i]);

How to convert blob into base64 in nextJs

I am getting the Image from an API response. I am trying to the get the image and display in the UI.
import FileReader from 'filereader';
export default async (req, res) => {
const { method } = req;
switch (method) {
case 'GET':
try {
const response = await fetch("imagepathurl", Constants.config);
const imageBlob = await response.blob()
console.log("imageBlob", imageBlob)
return new Promise((resolve, _) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(imageBlob);
});
} catch (error) {
console.log("error", error);
}
break
default:
res.setHeader('Allow', ['GET', 'PUT', 'PATCH'])
res.status(405).end(`Method ${method} Not Allowed`)
}
}
I can able to capture imageBlob but from the fileReader() i am unable to capture and convert to base64.
In File Reader i am facing Error: cannot read as File: {}.
Please let me know the way i am doing is correct or can soneone guide me in fixing it.

Download a by ByteArray as pdf /handle error in React

I have an api called from react. it returns a pdf file. When i click the link as href, i can download the pdf.
Now, instead of an href, i am calling a function , on clicking and from that function, i call the api. But i am not able to download the file.
This is what i am doing:
fetch(<url>, {
method: "GET",
headers: {
Accept: "application/pdf",
"Content-Type": "application/pdf",
},
}).then(response => response.blob())
.then(response => {
var blob=response
var reader = new window.FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function() {
var base64data = reader.result;
window.open(base64data);
}
})
.catch(error => {
console.error(error);
});
I am not able to download any file. The api (written in kotlin) returns a bytearray.
Also, if the api throws an exception instead of returning bytearray, i need to show a pop up ,
Any thoughts on this ?
To download the file you could use the file-saver npm package and use it as following:
import { saveAs } from 'file-saver';
const file = new Blob([blob]);
saveAs(file, 'fileName');
To open the file in your browser:
const file = new Blob([blob], {
type: 'application/pdf',
});
const fileURL = URL.createObjectURL(file);
window.open(fileURL);
You can create an invisible anchor tag somewhere in your component and use it. In my solution i created an invisible anchor tag with id invisible-link
async function download(payload) {
const response = await axios({
url: getFileLink(payload), responseType: 'blob'
})
if (response.status !== 200) {
// handle error
return
}
const anchor = document.getElementById('invisible-link')
const objectUrl = window.URL.createObjectURL(response.data)
anchor.href = objectUrl;
anchor.download = getDownloadFilename(response.headers)
anchor.click()
window.URL.revokeObjectURL(objectUrl)
}
function getDownloadFilename(headers = {}) {
const { 'content-disposition' : disposition = '' } = headers
const keyValue = disposition.split(';').find(e => e.includes('filename')) || ''
const [,filename] = keyValue.split('=')
return filename
}
here's a link of my code using this approach
// Function to download the file from byte array in REACT JS
const downloadPdfFromArrayBytes = (fileName = 'testFile.pdf', byteArrayResFromAPI) => {
const arr = new Uint8Array(array);
const blob = new Blob([arr]);
if (navigator.msSaveBlob) {
// IE 10+
navigator.msSaveBlob(blob, fileName);
} else {
const link = document.createElement('a');
// Browsers that support HTML5 download attribute
if (link.download !== undefined) {
const url = URL.createObjectURL(blob);
link.setAttribute('href', url);
link.setAttribute('download', fileName);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
};
// Example
// if you have api resp in byteArray as [10,12,30,20,34,49]
const fileName = 'myfileexample.pdf';
const apiResByteArr = [10,12,30,20,34,49];
downloadPdfFromArrayBytes(fileName ,apiResByteArr);

Resources