How to show upload progress of json data in axios, XMLHttpRequest, fetch? - reactjs

I'm trying to upload json data server in react-native. But the problem is, json data contain base64 image string. And I need display progress.
I tried like this, but it did not worked.
function handleEvent(e) {
setProgress((e.loaded / e.total) * 100)
}
function addListeners(xhr) {
xhr.upload.addEventListener('progress', handleEvent)
}
var xhr = new XMLHttpRequest();
addListeners(xhr);
xhr.open("POST", url);
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
console.log(xhr.status);
console.log(xhr.responseText);
}
};
xhr.send(JSON.stringify(payload));
and using axios
var res = await axios.post(BASE_URL + '/crossstorage_addfile', payload, {
headers, onUploadProgress: function (progressEvent) {
var percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total)
console.log(percentCompleted)
}
});
But nothing worked. Anything I can do resolve?
thank you.

Related

React Fetch download a pdf from Java REST API won't read in Adobe

I have tested the API in Postman and the PDF renders fine. So I know the API is working correctly.
When I fetch the PDF from within my React code Adobe gives me the error: "Adobe Acrobat cannot open the because it is neither a supported file type or because the file has been damaged"
My React code:
const downloadFile = async uploadId => {
const response = await callFetch("/uploads/download/" + uploadId + "?officerId=" + officerId, "GET", "");
if (response.status === 401 || response.status === 403) {
alert("Error " + response.status);
sessionStorage.clear();
return;
}
const file = response.blob();
const url = URL.createObjectURL(
new Blob([file], {type:"application/pdf"})
);
const link = document.createElement('a');
link.href = url;
link.setAttribute(
'download',
`FileName.pdf`,
);
// Append to html link element page
document.body.appendChild(link);
// Start download
link.click();
// Clean up and remove the link
link.parentNode.removeChild(link);
URL.revokeObjectURL(url);
};
const callFetch = (endpoint, method, jsonStr) => {
let myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Accept","application/json");
return callFetchApi(endpoint, method, jsonStr, myHeaders);
};
const callFetchApi = (endpoint, method, data, myHeaders) => {
const serverName = "http://localhost:8080/AuxPolice/api";
myHeaders.append("Access-Control-Allow-Credentials", 'true');
myHeaders.append("Access-Control-Allow-Origin", '*');
const jwt = sessionStorage.getItem("jwt");
let headerJwt = "Bearer " + jwt;
if (jwt != null) {
myHeaders.append("Authorization", headerJwt);
}
let myInit = {method: method
,headers: myHeaders
};
let url = serverName + endpoint;
if (data) {
myInit.body = data;
}
let returnFetch = fetch(url, myInit);
return returnFetch;
};
Here is my Java code:
#GetMapping(value = "/download" + "/{id}")
public ResponseEntity<Resource> downloadGet(#PathVariable Long id, #RequestParam Long officerId) throws SQLException
{
Officer loggedInOfficer = this.auxPoliceService.getOfficer(officerId);
Upload paramRec = new Upload();
paramRec.setUploadId(id);
Upload download = auxPoliceService.getUploads(loggedInOfficer.getOfficerId(), paramRec).get(0);
Blob blob = download.getBlob();
byte [] bytes = blob.getBytes(1, (int)blob.length());
blob.free();
InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(bytes));
String filename = download.getFilename();
String contentType = "application/pdf; name=\"" + filename() + "\"";
HttpHeaders headers = new HttpHeaders();
headers.set("content-disposition", "inline; filename=" + filename);
return ResponseEntity.ok()
.headers(headers)
.contentLength(bytes.length)
.contentType(MediaType.parseMediaType(contentType))
.body(resource);
}
Any ideas?

ionic 3 acces to json key

i can't access to a key of a json response from a restful web service.
{"_body":"{\"values\": {\"user_id\":\"1\",\"name\":\"fred test\",\"email\":\"fred#test.test\",\"username\":\"fredtest\",\"token\":\"d5f66a06ec809d70d0c52842df8dc0011d7d1ad0f2d56f50d3123da17a2489fe\"}}","status":200,"ok":true,"statusText":"OK","headers":{"pragma":["no-cache"],"content-type":["text/html;charset=UTF-8"],"cache-control":["no-store"," no-cache"," must-revalidate"],"expires":["Thu"," 19 Nov 1981 08:52:00 GMT"]},"type":2,"url":"http://localhost/PHP-Slim-Restful/api/login"}
I would like to acces to 'values' in this function: (this.responseData.values)
login(){
console.log('login'+ this.userData);
// Your app login API web service call triggers
this.authService.postData(this.userData,'login').then((result) => {
this.responseData = result;
console.log('userdata : '+ temp);
if(this.responseData.values){
console.log('response: ' + this.responseData);
localStorage.setItem('userData', JSON.stringify(this.responseData));
this.navCtrl.push(TabsPage);
}
else{
this.showToastWithCloseButton()
}
}, (err) => {
console.log('erreur : '+err);
});
}
I have an error undifined!
Can you help me?
I have used Observable to return json data and using the subscribe function in my method and using response.json() to convert the JSON reponse from RESTful webservices.
My component method,
import {Http, Headers, Response, RequestOptions} from '#angular/http';
import {Observable} from 'rxjs/Rx';
var response = this.service.post('deleteUserDetails/'+this.selectedUserId, null);
response.subscribe((res) => {
var response = res.json();
});
Service Post method,
post(url: string, data : any): Observable<any> {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
let options = new RequestOptions({ headers: headers});
return this.http.post(url, data,{headers: headers});
}
I think this might be helpful for your query.
You can make a for in your JSON and access the return values of your post. Something like that.
"this.responseData = result.json();" -> Return JSON. Make a for.
Example:
public postData(data, url: string) {
this.http.post(url, data).toPromise().then(res => {
let responseData = res.json();
if (responseData) {
for (var item of responseData) {
//Implments
}
}
}, (err) => {
});
}

XMLHttpRequest - sending arrays by _POST

With the old $.ajax method I would send arrays and normal data like so:
var dataARR = {
byteValue: 1,
data: []
};
Note data is an array.
dataARR.data.push({Username: "wazo", Info: "wazoinfo"});
dataARR.data.push({Username: "bifo", Info: "bifoinfo"});
Then getting it ready and sending:
var dataJSON = JSON.stringify(dataARR);
$.ajax({
type: "POST", // This for array
url: "login.php",
cache: false,
data: { myJson: dataJSON },
success: function (data) {
// Do stuff here
}
});
In the php code I would then do the following:
$dataTotal = json_decode($post['myJson'], true);
$Username0 = $dataTotal['data'][0]['Username'];
$Info0 = $dataTotal['data'][0]['Info']);
$Username1 = $dataTotal['data'][1]['Username'];
$Info1 = $dataTotal['data'][1]['Info']);
All that worked well.
However, now I am changing to XMLHttpRequest:
var url = "login.php";
var method = "POST";
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// XHR for Chrome/Firefox/Opera/Safari.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// XDomainRequest for IE.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
if (!xhr) {
return;
}
// Response handlers.
xhr.onload = function (data) {
// Do stuff
};
And the important bit
var dataJSON = JSON.stringify(dataARR);
xhr.send({ myJson: dataJSON });
But now the $_POST['myJson'] does not exist
When I do an echo print_r($_POST);, it returns Array()1
Question: What do I need to send in xhr.send(????); to get it so I can read the arrays in php again?
You access the data differently with XMLHttpRequest.
In the javascript:
var dataJSON = JSON.stringify(dataARR);
xhr.send(dataJSON);
In the php:
$dataTotal = json_decode(file_get_contents( "php://input" ), true);
$Username0 = $dataTotal['data'][0]['Username'];
$Info0 = $dataTotal['data'][0]['Info']);
$Username1 = $dataTotal['data'][1]['Username'];
$Info1 = $dataTotal['data'][1]['Info']);

Sending header parameters in angular2 and reading them from node

In my application I'm trying to send some header parameters from the angular2 application to my node server:
var token = localStorage.getItem('token');
var headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Auth-Token', token);
var url = this.baseUrl + '/initdata';
return this._http.get( url, {headers: headers, body : {}}).toPromise()
.then(response => {
const status = response.json().status;
if(status == SERVER_RESPONSE_STATUS.SUCCESS)
{
return response.json().result;
}
else if( status == SERVER_RESPONSE_STATUS.FAILED)
{
throw new Error(response.json().message);
}
})
.catch(this.handleError);
}
But the problem is when I'm trying to read the value from node, the value for "auth-token" cannot be extracted (saying undefined)
router.use('/', function (req, res, next) {
tokenGenerator.verify(req.header('auth-token'), Constants.AUTH_PRIVATE_KEY, function (err, decoded) {
});
});
in angular2, I'm importing Headers from http as well:
import {Http, Headers} from "#angular/http";
Can someone please help me what's the issue here?
Thanks
You can read tokens from header like this
if(req.headers.hasOwnProperty('token')) {
req.headers.authorization = 'Bearer ' + req.headers.token;
token = req.headers.token;
}
To send the token from Ng2
headers.append('token', token);
This us how I do it.

How to download files using axios.post from webapi

I have a complex object parameter that I need to send as post, as it could be too long for querystring. The post call is asking to have an excel file dynamically generated and then downloaded asynchronously. But all of this is happening inside of a react application. How does one do this using axios.post, react, and webapi? I have confirmed that the file does generate and the download up to the response does come back, but I'm not sure how to actually open the file. I have a hidden iframe that I'm trying to set the path, src, of the file to, but I dont know what response property to use.
// webapi
[HttpPost]
public HttpResponseMessage Post([FromBody]ExcelExportModel pModel)
{
var lFile = ProductDataModel.GetHoldingsExport(pModel);
var lResult = new HttpResponseMessage(HttpStatusCode.OK);
lResult.Content = new ByteArrayContent(lFile);
lResult.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "HoldingsGridExport.xls"
};
lResult.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
return lResult;
}
// client side api
static getHoldingsExport({ UserConfigurationID, UserID, Configurations, ViewName, SortModel, FilterModel, UserConfigType, IsDefault, LastPortfolioSearchID = null, ProductId }) {
const filterModel = JSON.stringify(FilterModel); // saving as string as this model is dynamically generated by grid out of my control
const sortModel = JSON.stringify(SortModel);
let params = JSON.stringify({
UserConfigurationID,
UserID,
Configurations,
ViewName,
filterModel,
sortModel,
UserConfigType,
IsDefault,
LastPortfolioSearchID,
ProductId
});
return axiosInstance.post("/api/HoldingsExport", params);
}
// client side app call to get file
HoldingsApi.getHoldingsExport(config)
.then(function(response) {
debugger;
let test = response;
})
.catch(error => {
toastr.success('Failed to get export.');
});
This is how I've achieved file downloads by POSTing via Axios:
Axios.post("YOUR API URI", {
// include your additional POSTed data here
responseType: "blob"
}).then((response) => {
let blob = new Blob([response.data], { type: extractContentType(response) }),
downloadUrl = window.URL.createObjectURL(blob),
filename = "",
disposition = response.headers["content-disposition"];
if (disposition && disposition.indexOf("attachment") !== -1) {
let filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/,
matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) {
filename = matches[1].replace(/['"]/g, "");
}
}
let a = document.createElement("a");
if (typeof a.download === "undefined") {
window.location.href = downloadUrl;
} else {
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
}
}).catch((error) => {
// ...
});
Just in case the above solution does not serve you quite well, here is how I could be able to download videos that are hosted on S3 AWS buckets,
const handleDownload = () => {
const link = document.createElement("a");
link.target = "_blank";
link.download = "YOUR_FILE_NAME"
axios
.get(url, {
responseType: "blob",
})
.then((res) => {
link.href = URL.createObjectURL(
new Blob([res.data], { type: "video/mp4" })
);
link.click();
});
};
And I trigger handleDownload function in a button with onClick.
The url in the function has the video URL from S3 buckets

Resources