I would like to render an image on React returned from FastAPI backend using StreamingResponse. The image is in the form of a numpy array, which is of cv2 type of object.
#app.post("/predict")
async def root(file: UploadFile = File(...)):
global model
global store_coordinates
global store_faces
global store_mesh
content = await file.read()
nparr = np.fromstring(content, np.uint8)
bg_img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
......................
for i in range(len(store_coordinates)):
x, y, w, h = store_coordinates[i]
bg_img [b:b + d, a:a + c] = store_mesh[i]
res,im_png = cv2.imencode(".png", bg_img)
return StreamingResponse(io.BytesIO(im_png.tobytes()), media_type="image/png")
Here, I have created an API endpoint in which the uploaded image is received using POST request, and a StreamableResponse(Image) is returned.
How can I render this returned response on React frontend?
React Code:
import React, { Component } from "react";
import axios from "axios";
class Detect extends Component {
state = {
title: "",
content: "",
image: null,
};
handleChange = (e) => {
this.setState({
[e.target.id]: e.target.value,
});
};
handleImageChange = (e) => {
this.setState({
image: e.target.files[0],
});
};
handleSubmit = (e) => {
e.preventDefault();
console.log(this.state);
let form_data = new FormData();
form_data.append("image", this.state.image, this.state.image.name);
let url = "http://127.0.0.1:8000/predict";
axios
.post(url, form_data, {
headers: {
"content-type": "multipart/form-data",
},
})
.then((res) => {
console.log(res.data);
})
.catch((err) => console.log(err));
};
render() {
return (
<div className="App">
<form onSubmit={this.handleSubmit}>
<p>
<input
type="file"
id="image"
accept="image/png, image/jpeg"
onChange={this.handleImageChange}
required
/>
</p>
<input type="submit" />
</form>
<div id="image-render">
<img></img>
</div>
</div>
);
}
}
export default Detect;
I would like to render the returned image in the div tag which has the id of image-render.
Edit - This is the response I get from my backend.
You could either encode the image data to Base64 format on server side and return the base64-encoded string, which can then be used to display the image in the HTML page as shown here (e.g., <img src="data:image/png;base64, ...), or send the raw bytes—it might be best not to use a StreamingResponse for sending the raw bytes, as you currently do, but rather use a custom Response, as shown in this and this answer, as the entire image bytes are already loaded into memory—and, on client side, convert them into either a base64-encoded string (using btoa(), String.fromCharCode() and Uint8Array), or a Blob object (and then call URL.createObjectURL() to create a URL representing the Blob object). The examples below show how to implement the last two methods (i.e., convert the image to either a base64-encoded string or Blob object on client side), using Axios library (which you seem to be using in your project), as well as Fetch API.
Using Axios
Option 1 - Convert raw image bytes into Blob object
axios({
method: 'POST',
url: '/upload',
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
},
responseType: "blob"
})
.then(response => {
var blobURL = URL.createObjectURL(response.data);
var image = document.getElementById("myImage");
image.onload = function(){
URL.revokeObjectURL(this.src); // release the blob URL once the image is loaded
}
image.src = blobURL;
})
.catch(error => {
console.error(error);
});
Option 2 - Convert raw image bytes into base64-encoded string
axios({
method: 'POST',
url: '/predict',
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
},
responseType: "arraybuffer"
})
.then(response => {
base64string = btoa(String.fromCharCode(...new Uint8Array(response.data)))
contentType = response.headers['content-type']
return base64string;
})
.then(base64string => {
var image = document.getElementById("myImage");
image.src = "data:" + contentType + ";base64," + base64string;
})
.catch(error => {
console.error(error);
});
Remember to define an <img> tag in your HTML file, where you wish to display the image:
<img id="myImage" src="">
Using Fetch API
Option 1 - Convert raw image bytes into Blob object
fetch('/predict', {
method: 'POST',
body: formData,
})
.then(response => response.blob())
.then(blob => {
var blobURL = URL.createObjectURL(blob);
var image = document.getElementById("myImage");
image.onload = function(){
URL.revokeObjectURL(this.src); // release the blob URL once the image is loaded
}
image.src = blobURL;
})
.catch(error => {
console.error(error);
});
Option 2 - Convert raw image bytes into base64-encoded string
fetch('/predict', {
method: 'POST',
body: formData,
})
.then(response => {
contentType = response.headers.get('content-type')
return response.arrayBuffer();
})
.then(arrayBuffer => {
base64string = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)))
var image = document.getElementById("myImage");
image.src = "data:" + contentType + ";base64," + base64string;
})
.catch(error => {
console.error(error);
});
Remember to define an <img> tag in your HTML file, where you wish to display the image:
<img id="myImage" src="">
Related
Using raw HTML when I post a file to a flask server using the following I can access files from the flask request global:
<form id="uploadForm" action='upload_file' role="form" method="post" enctype=multipart/form-data>
<input type="file" id="file" name="file">
<input type=submit value=Upload>
</form>
In flask:
def post(self):
if 'file' in request.files:
....
When I try to do the same with Axios the flask request global is empty:
<form id="uploadForm" enctype="multipart/form-data" v-on:change="uploadFile">
<input type="file" id="file" name="file">
</form>
uploadFile: function (event) {
const file = event.target.files[0]
axios.post('upload_file', file, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
If I use the same uploadFile function above but remove the headers json from the axios.post method I get in the form key of my flask request object a csv list of string values (file is a .csv).
How can I get a file object sent via axios?
Add the file to a formData object, and set the Content-Type header to multipart/form-data.
var formData = new FormData();
var imagefile = document.querySelector('#file');
formData.append("image", imagefile.files[0]);
axios.post('upload_file', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
Sample application using Vue. Requires a backend server running on localhost to process the request:
var app = new Vue({
el: "#app",
data: {
file: ''
},
methods: {
submitFile() {
let formData = new FormData();
formData.append('file', this.file);
console.log('>> formData >> ', formData);
// You should have a server side REST API
axios.post('http://localhost:8080/restapi/fileupload',
formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}
).then(function () {
console.log('SUCCESS!!');
})
.catch(function () {
console.log('FAILURE!!');
});
},
handleFileUpload() {
this.file = this.$refs.file.files[0];
console.log('>>>> 1st element in files array >>>> ', this.file);
}
}
});
https://codepen.io/pmarimuthu/pen/MqqaOE
If you don't want to use a FormData object (e.g. your API takes specific content-type signatures and multipart/formdata isn't one of them) then you can do this instead:
uploadFile: function (event) {
const file = event.target.files[0]
axios.post('upload_file', file, {
headers: {
'Content-Type': file.type
}
})
}
Sharing my experience with React & HTML input
Define input field
<input type="file" onChange={onChange} accept ="image/*"/>
Define onChange listener
const onChange = (e) => {
let url = "https://<server-url>/api/upload";
let file = e.target.files[0];
uploadFile(url, file);
};
const uploadFile = (url, file) => {
let formData = new FormData();
formData.append("file", file);
axios.post(url, formData, {
headers: {
"Content-Type": "multipart/form-data",
},
}).then((response) => {
fnSuccess(response);
}).catch((error) => {
fnFail(error);
});
};
const fnSuccess = (response) => {
//Add success handling
};
const fnFail = (error) => {
//Add failed handling
};
This works for me, I hope helps to someone.
var frm = $('#frm');
let formData = new FormData(frm[0]);
axios.post('your-url', formData)
.then(res => {
console.log({res});
}).catch(err => {
console.error({err});
});
this is my way:
var formData = new FormData(formElement);
// formData.append("image", imgFile.files[0]);
const res = await axios.post(
"link-handle",
formData,
{
headers: {
"Content-Type": "multipart/form-data",
},
}
);
How to post file using an object in memory (like a JSON object):
import axios from 'axios';
import * as FormData from 'form-data'
async function sendData(jsonData){
// const payload = JSON.stringify({ hello: 'world'});
const payload = JSON.stringify(jsonData);
const bufferObject = Buffer.from(payload, 'utf-8');
const file = new FormData();
file.append('upload_file', bufferObject, "b.json");
const response = await axios.post(
lovelyURL,
file,
headers: file.getHeaders()
).toPromise();
console.log(response?.data);
}
There is an issue with Axios version 0.25.0 > to 0.27.2 where FormData object in a PUT request is not handled correctly if you have appended more than one field but is fine with one field containing a file, POST works fine.
Also Axios 0.25.0+ automatically sets the correct headers so there is no need to specify Content-Type.
For me the error was the actual parameter name in my controller... Took me a while to figure out, perhaps it will help someone. Im using Next.js / .Net 6
Client:
export const test = async (event: any) => {
const token = useAuthStore.getState().token;
console.log(event + 'the event')
if (token) {
const formData = new FormData();
formData.append("img", event);
const res = await axios.post(baseUrl + '/products/uploadproductimage', formData, {
headers: {
'Authorization': `bearer ${token}`
}
})
return res
}
return null
}
Server:
[HttpPost("uploadproductimage")]
public async Task<ActionResult> UploadProductImage([FromForm] IFormFile image)
{
return Ok();
}
Error here because server is expecting param "image" and not "img:
formData.append("img", event);
public async Task<ActionResult> UploadProductImage([FromForm] IFormFile image)
I'm trying to upload a cropped image via client using fetch. The upload process works, the file size seems to be correct too but the uploaded image is corrupt and appears to be a white 16x16 square on the server. The file won't open when I download it (damaged or corrupt). I'm struggling to understand what I'm doing wrong. The back-end is Drupal.
Uploading files directly from an input using the same postFile function works without a problem.
const toFile = (blob) => {
blob.lastModifiedDate = new Date();
blob.name = 'cropped.png';
return blob;
}
const onCropperCrop = () => {
const imageElement = cropperRef?.current;
const cropper = imageElement?.cropper;
cropper.getCroppedCanvas().toBlob((blob) => {
const file = toFile(blob);
onCrop(file);
});
};
const onCrop = (file) => postFile(params);
export const postFile = async (
_file,
_uri,
_xcsrf_token,
_accessToken,
) => {
let formData = new FormData();
formData.append('File', _file);
let headers = {
headers: {
Accept: 'application/hal+json',
'Content-Type': 'application/octet-stream',
'Content-Disposition': 'file; filename="' + _file.name + '"',
'X-CSRF-Token': _xcsrf_token,
Authorization: 'Bearer ' + _accessToken,
},
};
return await fetch(_uri, {
method: 'POST',
headers: headers,
body: formData,
credentials: 'include'
});
};
The file object:
I think I have now tried everything and read every question on this matter, but still I can't make it to work..
Cart.vue
<template>
<div>
<h1>CART</h1>
<img :src="imgSrc" style="width:600px; height: 600px">
</div>
</template>
Cart.vue mounted()
mounted(){
const qr = firebase.functions().httpsCallable('sendPaymentRequest')
qr()
.then(res => {
const blob = new Blob([res.data], {type: 'image/jpg'})
console.log(blob);
const url = (window.URL || window.webkitURL).createObjectURL(blob)
console.log(url);
this.imgSrc = url;
})
Firebase functions
exports.sendPaymentRequest = functions.https.onCall((data, context) => {
const qr = async () => {
try {
const json = {
token: "umP7Eg2HT_OUId8Mc0FHPCxhX3Hkh4qI",
size: "300",
format: "jpg",
border: "0"
}
const response = await axios.post('https://mpc.getswish.net/qrg-swish/api/v1/commerce', json)
console.log('status', response.status)
if(response.status !== 200){throw new Error ('Error requesting QR code')}
return response.data
} catch (e){
console.log('error', e)
return e
}
}
return qr();
})
In my 2 console logs in the mounted() hook - the Blob and the URL - I get:
Looking pretty all right? There seem to be a Blob? And a URL?
however:
... sooo I tried changing the mounted() to
const qr = firebase.functions().httpsCallable('sendPaymentRequest')
qr()
.then(res => {
const self = this;
const blob = new Blob([res.data], {type: 'image/jpg'})
const reader = new FileReader();
reader.onloadend = function() {
self.imgSrc = reader.result
};
reader.readAsDataURL(blob);
})
.catch(e => console.log(e))
which also seem to work but.. well it's not.. Now I got a nice little base64-encoded string to my image instead of URL:
But still no image..
So I tried some other stuff I found while reading all of Internet.. moving from a callable function to onRequest function etc.. When I'm doing the exact same request with Postman I'm getting a fine QR code in the response..
If I'm loggin the response.headers in firebase functions I'm seeing
'content-type': 'image/jpeg',
'content-length': '31476',
So on the server I'm getting an image.. which I'm sending with return response.data
response.data being:
����JFIF��C
$.' ",#(7),01444'9=82<.342��C
2!!22222222222222222222222222222222222222222222222222�,,"��
and so on..
And that's where I'm at.. I'm getting .. frustrated.
Does anyone on here see what I'm doing wrong??
EDIT 1
for anyone running into this in the future - as #Kaiido points out on client I have to add
...
responseType: "blob"
}
but also on server, with firebase you need to move from
functions.https.onCall(async (data, context) => {
to
functions.https.onRequest(async (req, res) => {
call it on client with:
axios({
method: 'get',
url: 'http://localhost:5001/swook-4f328/us-central1/retrieveQr',
responseType: 'blob',
})
.then(async res => {
const url = (window.URL || window.webkitURL).createObjectURL(res.data)
this.imgSrc = url;
})
.catch(e => e)
and on server instead of axios use request (for some reason, but this works.. no idea why, but solves problem for now though I would be curious to why and I prefer axios to request)
works
const json = {
token: "umP7Eg2HT_OUId8Mc0FHPCxhX3Hkh4qI",
size: "300",
format: "png",
border: "0"
}
var requestSettings = {
url: 'https://mpc.getswish.net/qrg-swish/api/v1/commerce',
method: 'POST',
encoding: null,
json: true,
'content-type': 'application/json',
body: json,
};
request(requestSettings, (error, response, body) => {
res.set('Content-Type', 'image/png');
res.header({"Access-Control-Allow-Origin": "*"});
res.send(body);
});
does not work
const json = {
token: "umP7Eg2HT_OUId8Mc0FHPCxhX3Hkh4qI",
size: "300",
format: "png",
border: "0"
}
const response = await axios.post('https://mpc.getswish.net/qrg-swish/api/v1/commerce', json)
if(response.status !== 200){throw new Error ('Error requesting QR code')}
res.header({"Access-Control-Allow-Origin": "*"}).writeHead(200, {'Content-Type': 'image/png'}).end(response.data)
// neither this works:
// res.header({"Access-Control-Allow-Origin": "*"}).status(200).send(response.data)
You are receiving an utf8 encoded text, some bytes from the binary response have been mangled.
When doing your request, add an extra
...
responseType: "blob"
}
option to your axios request, this will ensure the binary data is not read as text but preserved correctly.
Plus now you don't need to build the Blob yourself, it is already one in response.data.
I am working with antd framework and I have to use upload API.
This is the signature:
action: Uploading URL : string|(file) => Promise
I am invoking the API in this way trying to return a Promise:
<Upload {...propsUpload}>
<Button> <Icon type="upload" />Upload</Button>
</Upload>
with propsUpload that refers to function uploadMedia
const propsUpload = {
action: this.uploadMedia,
listType: 'picture',
defaultFileList: [],
className: 'upload-list-inline',
};
and this is the function uploadMedia
uploadMedia = (file) => {
let formData = new FormData();
formData.append('file', file);
formData.append('uuid', this.generateuuid());
formData.append('domain', 'POST');
formData.append('filename', file.name );
return fetch(process.env.REACT_APP_API_URL +
'/v100/media/upload', {
method: 'POST',
credentials: 'include',
headers: {
Accept: 'application/json'
},
body: formData
})
.then(response => response.json())
.then(data => data.data)
.catch(error => {
console.log('Error fetching profile ' + error)
})
}
The file is uploaded to server correctly.
But after the call to API, antd try to do another call that fails, maybe because I am not returning the correct value from function.
As result the thumbnail is displayed with red border and and error is shownd. In the image below there are both (the call that fails and image with red border)
What type of object I have to return in function uploadMedia to use api correctly?
Thanks
I haven't used antd but looking at the docs of Uplaod component I think you're using it wrong. Look at the examples there and see the code, action expects either a URL or a Promise that will return this URl. And Upload in this case will make request itself, so you don't need to do fetch. And your promise returns the data (object) so the Upload sends the request to [object Object] (which is what's returned by .toString() when applied to an object in JS)
EDIT
Try to check all examples in docs, I can see that there is an example when you want to manually upload the file (if you really need it)
For anyone looking to access the response object after calling the API. There are two ways you can get access to the response.
Implement a custom API request mentioned as in other answers for this question.
Use the onChange method provided by AntD (Which is the easier than utilizing the custom request)
I will explain the second approach below using a code block.
const fileUploadProps = {
name: "file",
action: config.remote + "api/file",
method: "POST",
showUploadList: false,
headers: {
authorization: "authorization-text",
contentType: "multipart/form-data"
},
onChange(info) {
if (info.file.status === "done") {
const { response } = info.file;
updateProfile(response.payload.file);
} else if (info.file.status === "error") {
message.error("Error uploading the file");
props.endLoad();
}
},
beforeUpload(file) {
const isJpgOrPng = file.type === "image/jpeg" || file.type === "image/png";
if (!isJpgOrPng) {
message.error("You can only upload JPG/PNG file!");
}
const isLt2M = file.size / 1024 / 1024 < 2;
const isGT20K = file.size / 1024 > 20;
if (!isLt2M) {
message.error("Image must smaller than 2MB!");
}
if (!isGT20K) {
message.error("Image must larger than 20KB!");
}
if (isJpgOrPng && isLt2M && isGT20K) {
props.startLoad();
return true;
} else {
return false;
}
}
};
In Render function I have the AntD upload component
<Upload {...fileUploadProps}>
<Button icon={<CameraFilled style={{ fontSize: "30px" }} />}></Button>
</Upload>
You can notice how I got the access to the response object inside onChange function.
Once the upload is complete it will call the onChange function having response object inside the info object.
So from there you can get access to your data object easily and call the next method.
I solved using api customRequest in this way:
uploadMedia = (componentsData) => {
let formData = new FormData();
formData.append('file', componentsData.file);
formData.append('uuid', this.generateuuid());
formData.append('domain', 'POST');
formData.append('filename', componentsData.file.name );
fetch(process.env.REACT_APP_API_URL + '/v100/media/upload', {
method: 'POST',
credentials: 'include',
headers: {
Accept: 'application/json'
},
body: formData
})
.then(response => response.json())
.then(data => data.data)
.then(data=> componentsData.onSuccess())
.catch(error => {
console.log('Error fetching profile ' + error)
componentsData.onError("Error uploading image")
})
}
For those who are not clear how to actually implement it (and it is unclear in docs):
Just implement a customRequest function in the props that accepts two callbacks, which are onError and onSuccess, and other data such as file and filename.
Like this
const props = {
customRequest: (componentsData) => {
let formData = new FormData();
formData.append('file', componentsData.file);
formData.append('uuid', this.generateuuid());
formData.append('domain', 'POST');
formData.append('filename', componentsData.file.name );
fetch(process.env.REACT_APP_API_URL + '/v100/media/upload', {
method: 'POST',
credentials: 'include',
headers: {
Accept: 'application/json'
},
body: formData
})
.then(response => response.json())
.then(data => data.data)
.then(data=> componentsData.onSuccess())
.catch(error => {
console.log('Error fetching profile ' + error)
componentsData.onError("Error uploading image")
})
}
}
And let Upload component receive the props.
const App = () => {
return <Upload {...props} />
}
I am sending the below response from my REST Api .
{
"value": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PC9TL0phdmFTY3JpcHQvSlModGhpcy56b29tID0gMTAwOyk+PgplbmRvYmoKNSAwIG9iago8PC9Db2xvclNwYWNlL0RldmljZUdyYXkvU3VidHlwZS9JbWFnZS9IZWlnaHQgMTUwL0ZpbHRlci9GbGF0ZURlY29kZS9UeXBlL1hPYmphkNkwEVng0L00DhlcQ6ysIV4GNaOajLDQGlbKEIuFcJchdvr0W/z0aY+lZJyy+pmGsnrODq3AQiAQCAQCiRDHKaRFx0iOEAGhh40g1P0IsjS9pXbPlEzDoYf1OKTkDjFdQ6ysIXaYzMRC17KaLtIpQxdTKUPs9Gm646LMQnT6NJeFXjazUIotCx3mrcWQabf6qG8iEAgEAoEmsW7jOIXU6BidLK2BkEZBFP88qhr9R42IKBwiqdSMSBnlGjL2GlLDZOZqMuuUIZsuQ5bp0/xSMkdl9YZdyfy1GOK2W4z6JgKBQCAQaBJLFyDTZwphpxCJjpHQGGYbPAn/JQ/DX/YVtf/Rq19v18QeBP+Sh+Gv+wra/+jVr7foAKKKKACiiigD5g/aO/wCSh6f/ANgqP/0bLXj9ewftHf8AJQ9P/wCwVH/6Nlrx+gAooooAK6DwJ/yUPw1/2FbX/wBGrXP10HgT/kofhr/sK2v/AKNWgD7fooooA8f/AGjv+Seaf/2FY/8A0VLXzBX0/wDtHf8AJPNP/wCwrH/6Klr5goAK+n/2cf8Aknmof9hWT/0VFXzBX0/+zj/yTzUP+wrJ/wCioqAPYKKKKACiiigAooooAKKKKACiiigD5g/aO/5KHp//AGCo/wD0bLXj9ewftHf8lD0//sFR/wDo2WvH6ACvt/wJ/wAk88Nf9gq1/wDRS18QV9v+BP8Aknnhr/sFWv8A6KWgDoK5/wAd/wDJPPEv/YKuv/RTV0Fc/wCO/wDknniX/sFXX/opqAPiCiiigAooooAKKKKACiiigAooooA6DwJ/yUPw1/2FbX/0atfb9fEHgT/kofhr/sK2v/o1a+36ACiiigAooooAKKKKACviDx3/AMlD8S/9hW6/9GtX2/XxB47/AOSh+Jf+wrdf+jWoA5+ug8Cf8lD8Nf8AYVtf/Rq1z9dB4E/5KH4a/wCwra/+jVoA+36KKKAPH/2jv+Seaf8A9hWP/wBFS18wV9P/ALR3/JPNP/7Csf8A6Klr5goAK+n/ANnH/knmof8AYVk/9FRV8wV9P/s4/wDJPNQ/7Csn/oqKgD2CiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK4P4s+NdS8B+FbXVNLgtJp5b1LdlukZlClHbI2spzlB39a7yvH/wBo7/knmn/9hWP/ANFS0AcB/wANHeMP+gbof/fib/47R/w0d4w/6Buh/wDfib/47Xj9FAH0P4b8N2fx306TxR4okns761lOnpHpjCOMxqBICRIHO7Mrc5xgDj12P+GcfB//AEEtc/7/AMP/AMao/Zx/5J5qH/YVk/8ARUVewUAeP/8ADOPg/wD6CWuf9/4f/jVcRf8Axr8SeDtRufC+nWWlS2OjSvp9vJcRSNI0cJMalyJACxCjJAAz2FfS9fEHjv8A5KH4l/7Ct1/6NagD0D/ho7xh/wBA3Q/+/E3/AMdqnq3x98Vazo19pdxp+jLBe28lvI0cMoYK6lSRmQjOD6GvK6KACiiigD2D9nH/AJKHqH/YKk/9GxV9P18wfs4/8lD1D/sFSf8Ao2KvKACiiigAooooAKKKKACvmD9o7/8L0luZm8gMjQgMCBSL0lEIFs8YzkyMWI2MGVkYzdkYTVlZWQyMzYyNTliYWRiYTVjMGY+PDMzYWYzZTBkOGM1MjFhNzVlMjk2MGQwZDIzZjJkY2U2Pl0vUm9vdCAyMyAwIFIvU2l6ZSAyNT4+CnN0YXJ0eHJlZgoxODA2OTIKJSVFT0YK",
"transid": "transid"
}
I am trying to convert the value which is byte data to pdf using React js.
Below is my implementation:
handleSubmit = e => {
e.preventDefault();
let url = "http://localhost:8080/getPDF"
fetch(url, {
method: "POST",
body: JSON.stringify(this.state.transId),
})
responseType: 'blob'
.then(response => {
//Create a Blob from the PDF Stream
const file = new Blob(
[response.value],
{type: 'application/pdf'});
//Build a URL from the file
const fileURL = URL.createObjectURL(file);
//Open the URL on new Window
window.open(fileURL);
})
.catch(error => {
console.log(error);
});
};
But I am getting the following error.Can anyone please suggest where I am going wrong?
Uncaught TypeError: "blob".then is not a function
You cannot do .then() after a string (must follow a promise). You probably meant this line responseType: 'blob' to be one line higher up, inside the object?
handleSubmit = e => {
e.preventDefault();
let url = "http://localhost:8080/getPDF"
fetch(url, {
method: "POST",
body: JSON.stringify(this.state.transId),
responseType: 'blob' // <-- MOVE THIS LINE INTO REQUEST
})
.then(response => {
//Create a Blob from the PDF Stream
const file = new Blob(
[response.value],
{type: 'application/pdf'});
//Build a URL from the file
const fileURL = URL.createObjectURL(file);
//Open the URL on new Window
window.open(fileURL);
})
.catch(error => {
console.log(error);
});
};