Download PDF using Angular - angularjs

I'm trying to download PDF from a WebApi using Angular but the file is only 15 bytes. If I log the data being received from the WebApi it's an arraybuffer with the expected size
The WebApi
[HttpGet]
public HttpResponseMessage MatchRegistrationReport(int matchId)
{
try
{
var gen = new MSReports.Components.MatchRegistration();
byte[] bytes = gen.GeneratePDF(matchId, 10);
var stream = new MemoryStream(bytes);
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(stream)
//Content = new ByteArrayContent(bytes)
};
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = gen.ReportName + ".pdf"
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
return result;
}
catch (Exception ex)
{
Log.Error(ex.Message);
return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message);
}
}
The Angular controller
$scope.Print = function () {
$scope.message = "Downloading";
reportResource.printMatchRegistration($scope.match.Id).then(function (data, status, headers, config) {
var file = new Blob([data], {
type: 'application/csv'
});
//trick to download store a file having its URL
var fileURL = URL.createObjectURL(file);
var a = document.createElement('a');
a.href = fileURL;
a.target = '_blank';
a.download = 'MatchRegistration.pdf';
document.body.appendChild(a);
a.click();
//$scope.message = "Completed";
}, function (data, status, headers, config) {
$scope.message = "A error occurred";
});
}
and the resource
printMatchRegistration: function (matchId) {
return $http({
method: 'get',
url: this.getApiPath() + "MatchRegistrationReport?matchId=" + matchId,
headers: {
'Content-type': 'application/pdf',
},
responseType: 'arraybuffer'
});
I believe it has something to do with the content-type but can' figure out what.

Hi just found the answer
Change to this
reportResource.printMatchRegistration($scope.match.Id).then(function (response) {
var file = new Blob([response.data], {
type: 'application/pdf'
});
and this
printMatchRegistration: function (matchId) {
var data = { 'matchId': matchId };
return $http({
method: 'get',
url: this.getApiPath() + "MatchRegistrationReport",
params: data,
headers: {
'Content-type': 'application/pdf',
},
responseType: 'arraybuffer'
});
},

Related

File download not working in Safari?

I have developed an angular JS web application with PDF file download functionality. It doesn't work in Safari.
$http({
method: 'GET',
url: common.serviceUrl(config.apiServices.usermanuals),
params: { manualId: manualId },
responseType: 'arraybuffer'
}).success(function (data, status, headers, config) {
headers = headers();
//var test = headers('Content-Disposition');
var filename = headers['x-filename'];
var contentType = headers['content-type'];
var linkElement = document.createElement('a');
try {
var blob = new Blob([data], { type: contentType });
var url = window.URL.createObjectURL(blob);
linkElement.setAttribute('href', url);
linkElement.setAttribute("download", filename);
var clickEvent = new MouseEvent("click", {
"view": window,
"bubbles": true,
"cancelable": false
});
linkElement.dispatchEvent(clickEvent);
} catch (ex) {
console.log(ex);
}
}).error(function (data) {
console.log(data);
});
Please help me find a workaround to this. Thank you
Try using FileSaver
var file = new Blob([data], { type: 'application/pdf;charset=utf-8' });
FileSaver.saveAs(file, filename);
*data is coming from api response,
*filename you can pass as abc.pdf

Fill angular model from response

I am getting response like
StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.ByteArrayContent, Headers:
{
x-filename: StatementofAccount.pdf
Content-Type: application/octet-stream
Content-Disposition: attachment; filename=StatementofAccount.pdf
}
now i need to use "x-filename: StatementofAccount.pdf" but i am not able to fetch this.
I fill this response to my model like
$scope.dataDetail = response.data;
but when I tried to get
console.log($scope.dataDetail.StatusCode)
or
console.log($scope.dataDetail.Headers.x-filename)
but its showing undefined.
plz get me an idea where i am doing wrong or how to achieve this.
I tried from the following way..plz get me idea where i am wrong.....
c#
....
byte[] bytes = memoryStream.ToArray();
memoryStream.Close();
httpResponseMessage.Content = new ByteArrayContent(bytes.ToArray());
httpResponseMessage.Content.Headers.Add("x-filename", fileName);
httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
httpResponseMessage.Content.Headers.ContentDisposition.FileName = fileName;
httpResponseMessage.StatusCode = HttpStatusCode.OK;
return httpResponseMessage;
in angularjs
$http({
method: 'post',
url: basePath + '/profile/downloadpdf_fromedit',
// data: JSON.stringify($scope.paginginfostmntaccnt),
responsetype: 'arraybuffer',
headers: {'content-type': 'application/pdf'},
// headers: { 'content-type': 'application/json' }
})
.then(function (response) {
// console.log(response.data);
$scope.dataDetail = response.data;
console.log($scope.dataDetail)
1. var file = new Blob([response.data], { type: 'application/pdf' });
saveAs(file, 'StatementofAccount.pdf');
//url-file:///C:/Users/tushar/Downloads/StatementofAccount.pdf
//failed to load pdf
2.var file = new Blob([response], { type: 'application/pdf' });
var fileurl = URL.createObjectURL(file);
window.open(fileurl);
//url- blob:http://localhost:16311/02f8d85e-74c0-4ccd-b937-22f02cc3866c
//failed to load pdf document
3.
.success(function (data, status, headers, config) {
// any required additional processing here
var results = [];
results.data = data;
results.headers = headers();
results.status = status;
results.config = config;
console.log(results)
$("#loading").hide();
headers = headers();
var filename = headers['x-filename'];
var contentType = headers['content-type'];
if (!filename) {
filename = headers["x-filename"] || 'statementAccount.pdf';
}
var linkElement = document.createElement('a');
try {
var blob = new Blob([data], { type: contentType });
var url = window.URL.createObjectURL(blob);
linkElement.setAttribute('href', url);
linkElement.setAttribute("download", filename);
var clickEvent = new MouseEvent("click", {
"view": window,
"bubbles": true,
"cancelable": false
});
linkElement.dispatchEvent(clickEvent);
$("#loading").hide();
console.log("filename" + filename);
} catch (ex) {
console.log("catch"+ex);
$("#loading").hide();
}
})
//url-file:///C:/Users/tushar/Downloads/statementAccount.pdf
//failed to load pdf document
To access the headers of the response you need to use response.headers instead of response.data the data portion contains body of the response.

How to Download binary file in angular js using http

I want to downlaod exe file using $http, it shows me when I console the data, but I am unable to download it.
$http({
url: url,
method: "GET",
headers: {
'Content-type': 'application/json'
}
}).success(function (data, status, headers, config) {
console.log(data);
window.open(objectUrl);
}).error(function (data, status, headers, config) {
//upload failed
});
Any help would be appreciated.
you can Use response type like responseType: "arraybuffer"
$http({
url: url,
method: "GET",
headers: {
'Content-type': 'application/json'
},
responseType: "arraybuffer"
}).success(function (data, status, headers, config) {
console.log(data);
var file = new Blob([data], { type: 'application/binary' });
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
var link=document.createElement('a');
link.href=fileURL;
link.download="testing.exe";
link.click();
window.open(objectUrl);
}).error(function (data, status, headers, config) {
//upload failed
});
and use Blob and pass type "application/binary" and create a link to download it.
Given code will help you to download exe file as well as to check
browser compatibility.
var ieEDGE = navigator.userAgent.match(/Edge/g);
var ie = navigator.userAgent.match(/.NET/g); // IE 11+
var oldIE = navigator.userAgent.match(/MSIE/g);
var blob = new window.Blob([data.data], { type: 'application/x-msdownload' });
if (ie || oldIE || ieEDGE) {
var fileName="filename"+'.exe';
window.navigator.msSaveBlob(blob, fileName);
}
else {
var file = new Blob([ data.data ], {
type : 'application/x-msdownload'
});
var fileURL = URL.createObjectURL(file);
var a = document.createElement('a');
a.href = fileURL;
a.target = '_blank';
a.download = "filename"+'.exe';
document.body.appendChild(a);
a.click();
}
//Successfully Downloaded

How can I post data as form data with Angular

I want to send an avatar to my server but I have this error "You must include 'avatar' file var in your POST form data."
function getPictureSuccess(imageData) {
var image = "data:image/jpeg;base64," + imageData;
$scope.avatar = image;
}
$http({
url: api_url + 'userplus/avatar_upload/?key=' + api_key + '&cookie=' + dataCookie,
method:"POST",
headers : {'Content-Type': 'application/x-www-form-urlencoded'},
data: {avatar: avatar}
});
Change data: {avatar: avatar} to data: {avatar: $scope.avatar}
try
imgURI = "data:image/jpeg;base64," + imageData;
var FD = new FormData();
FD.append('image', dataURItoBlob(imgURI), 'image.jpg'); // "image" This is what you get at server side so change it accord inly
FD.append("Other Param", 'other Param value ') // other parameter needed to post
$http.post('Your Url', DataObj, {
headers: {
'Content-Type': undefined
},
transformRequest: angular.identity
}).then(function(responce) {
responce.data;
})
// And here is your helper function
function dataURItoBlob(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString = atob(dataURI.split(',')[1]);
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
var bb = new Blob([ab], {
"type": mimeString
});
return bb;
}

PUT request to Amazon S3 bucket using presigned url returns 403

I'm getting the presigned url from a Node.js server using aws-sdk. Here is the server code, which always returns a 200 code and a the url:
getSignedUrl: function(req, res, next){
aws.config.update({ accessKeyId: AWS_ACCESS_KEY, secretAccessKey: AWS_SECRET_KEY });
var s3 = new aws.S3();
var s3_params = {
Bucket: S3_BUCKET,
Key: req.query.file_name,
ContentType: req.query.file_type,
ACL: 'public-read'
};
s3.getSignedUrl('putObject', s3_params, function(err, data){
if (err) {
return next(err);
}
else {
var return_data = {
signed_request: data,
url: 'https://'+S3_BUCKET+'.s3.amazonaws.com/'+req.query.file_name
};
res.json(return_data);
}
});
}
My client-side is Angular. I've uloaded a file using a File Reader service:
.factory('fileReaderFactory', ['$q', '$log', function($q, $log){
....
var getReader = function(deferred, scope) {
var reader = new FileReader();
....
return reader;
};
var readAsDataURL = function (file, scope) {
var deferred = $q.defer();
var reader = getReader(deferred, scope);
scope.$broadcast("fileData", {
name: file.name,
type: file.type
});
reader.readAsDataURL(file);
return deferred.promise;
};
return {
readAsDataUrl: readAsDataURL
};
}]);
My controller:
.controller('UploadCtrl', ['apiFactory','fileReaderFactory','$scope', function(apiFactory, fileReaderFactory, $scope){
$scope.data = {};
$scope.fileData = {};
...
$scope.readFile = function() {
fileReaderFactory.readAsDataUrl($scope.file, $scope)
.then(function(result){
$scope.imgSrc = result;
imgUploaded = true;
});
};
$scope.upload = function(){
apiFactory.getSignedUrl($scope.fileData)
.then(function(result){
return apiFactory.uploadS3(result, $scope.fileData, $scope.imgSrc);
})
.then(function(result){
}, function(error){
console.log(error);
})
};
....
}]);
And finally the snippets of code from the apiFactory:
apiFactory.getSignedUrl = function(data){
return $http({
method: 'GET',
url: API_URL + '/sign_s3',
params : {
"file_name": data.name,
"file_type": data.type,
}
});
};
apiFactory.uploadS3 = function(result, data, file){
return $http({
method: 'PUT',
url: result.data.signed_request,
data: file,
headers: {
"x-amz-acl": "public-read"
}
});
}
I always get a 403: Forbidden back from Amazon when I try to upload the file using the signed url, however.

Resources