FormData append not working with $http post - angularjs

I want to submit info to an online server and it requires that I send that using FormData.
So I am using the following function for that
var my_app = angular.module("my-app",[])
my_app.controller("MainController", function($scope, $http){
$scope.master = {title: "Title",desc: "Desctibe", tags: ["One","Two"], category: ["1","2"] };
var url = "http://freedoctor.southeastasia.cloudapp.azure.com/api/forum/create";
var config = {"headers":{"Authorization":"JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjU5MzEwNDUxZjk3MjJmZTQyODE1NTIxYSIsInJvbGUiOiJwYXRpZW50IiwiaWF0IjoxNDk3NDE4ODA3fQ.ODrSlYwxvrPb93IzHW3s-7NIVFsOL4pKzqZx8yMqWWE"}};
$scope.booking = function(){
$scope.title=$scope.user.title;
$scope.desc=$scope.user.desc;
$scope.tags=$scope.user.tags;
$scope.category=$scope.user.category;
$scope.askedTo=$scope.user.askedTo;
var info = new FormData();
info.append("title", $scope.title);
info.append("desc", $scope.desc);
info.append("tags", $scope.tags);
info.append("category", $scope.category);
$http.post("http://localhost:8080/"+url, info, config).then(
function(response){
console.log(response);
$scope.reply = response.data;
},
function(response){
console.log(response);
$scope.reply = response.data;
});
}
$scope.reset = function() {
$scope.user = angular.copy($scope.master);
};
$scope.reset();
});
So whenever I call booking function I get an internal server error
SyntaxError: Unexpected token -
at parse (/home/freedoctor/fdhbackend/node_modules/body-parser/lib/types/json.js:83:15)
at /home/freedoctor/fdhbackend/node_modules/body-parser/lib/read.js:116:18
at invokeCallback (/home/freedoctor/fdhbackend/node_modules/raw-body/index.js:262:16)
at done (/home/freedoctor/fdhbackend/node_modules/raw-body/index.js:251:7)
at IncomingMessage.onEnd (/home/freedoctor/fdhbackend/node_modules/raw-body/index.js:307:7)
at emitNone (events.js:86:13)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickDomainCallback (internal/process/next_tick.js:122:9)
I know the FormData is working as i checked it out with this
for (var pair of info.entries()) {
console.log(pair[0]+ ', ' + pair[1]);
}

The additional data that you are trying to pass along the formData object should be appended to the data property of the FormData Object. I once wrote the following function. Should work for you too:
this.uploadFile = function (url, dataToUpload) {
var data = new FormData();
data.append("file", dataToUpload.file); //if you want to upload files along, else ignore this line
data.append("data", angular.toJson(dataToUpload.data)); //you can pass an object containing additional data and then append it here to the data property
return $http.post(url, data, {
transformRequest: angular.identity,
headers: { 'Content-Type': undefined }
});
}
You can chain your .then callbacks to the returned object from this function.
Try this and update if you face any issue.

Related

Pass array of data in angularjs multipart

I have an array of colors and sizes, and some other data like product_name and images, I am able to send image files and product_name but when I attach color_and_sizes array then it says 500 error
Here is my Code :(Angularjs and Laravel Controller )
Basically I want to save all the details in the database but I am unable to save the color and sizez details.
$scope.admin_add_product=function(){
var product_name=$scope.txtProductname;
var product_description=$scope.tarDescription;
var price=$scope.txtprice;
var unit_in_stock=$scope.txtunitinstock;
var unit_weight=$scope.txtweight;
var file = $scope.front_image;
var file2=$scope.back_image;
var file3=$scope.left_side_image;
var file4=$scope.right_side_image;
var main_image=$scope.main_image;
var large_image=$scope.large_image;
var category_id=$scope.selectedCategory.category_id;
var sub_category_id=$scope.selectedSubCategory.sub_category_id;
var sub_sub_category_id=$scope.selectedSubSubCategory.sub_sub_category_id;
var product_key=$scope.addProductOption;
var tags=$scope.txt_tags;
var aditional_information=$scope.txt_aditional_information;
var temp_color_and_size=[];
temp_color_and_size=$scope.color_and_size;
console.log(temp_color_and_size);
var uploadUrl = 'http://web.com/app/add_product';
fileUpload.uploadFileToUrl(file,file2,file3,file4,main_image,large_image, product_name,product_description,price,category_id,sub_category_id,sub_sub_category_id,unit_in_stock,unit_weight,product_key,tags,aditional_information ,temp_color_and_size, uploadUrl);
}
/* ---------------------------------------------------- Color and Sizes -------------------------------------------------- */
$scope.color_and_size=[];
$scope.Add=function(){
var c_and_s=[];
c_and_s.color_name = document.getElementById('cl1').value;
var s;
if($scope.sizes!=null)
{
for(var i=0;i<$scope.sizes.length-1;i++)
{
if($scope.sizes[i+1]>=0 && $scope.sizes[i+1]<=9)
{
}
else
{
if($scope.sizes[i+2]>=0 && $scope.sizes[i+2]<=9)
{
}
else
{
$scope.sizes = $scope.sizes.substring(0, i+1);
}
}
}
console.log($scope.sizes);
$scope.size=$scope.sizes.split(',');
c_and_s.sizes=$scope.size;
}
$scope.color_and_size.splice(0,0,c_and_s);
console.log($scope.color_and_size);
document.getElementById('cl1').value="#000000";
$scope.sizes="";
}
myApp.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file,file2,file3,file4,main_image,large_image,product_name,product_description,price,category_id,sub_category_id,sub_sub_category_id,unit_in_stock,unit_weight,product_key,tags,aditional_information,temp_color_and_size, uploadUrl){
console.log(product_name);
console.log(product_description);
console.log(price);
console.log(unit_in_stock);
console.log(unit_weight);
console.log(file);
console.log(temp_color_and_size);
console.log(product_key);
console.log(tags);
console.log(aditional_information);
var payload = new FormData();
payload.append("product_name", product_name);
payload.append('product_description', product_description);
payload.append('price', price);
payload.append('unit_in_stock', unit_in_stock);
payload.append('unit_weight', unit_weight);
payload.append('file', file);
payload.append('file2', file2);
payload.append('file3', file3);
payload.append('file4', file4);
payload.append('main_image', main_image);
payload.append('large_image', large_image);
payload.append('product_key', product_key);
payload.append('tags', tags);
payload.append('aditional_information', aditional_information);
payload.append('temp_color_and_size', temp_color_and_size);
return $http({
url: uploadUrl,
method: 'POST',
data: payload,
//assign content-type as undefined, the browser
//will assign the correct boundary for us
headers: { 'Content-Type': undefined},
//prevents serializing payload. don't do it.
transformRequest: angular.identity
})
.then(function (response){
alert('Product Added Successfully');
window.location = "http://web.com/add_product"
},function (error){
});
}
}]);
Please help me to resolve this problem.
Your question is not clear to me but I think the problem is that all properties of the formData object apart from temp_color_and_size are string type and temp_color_and_size is a javascript object. This might solve your problem.
payload.append('temp_color_and_size', JSON.stringify(temp_color_and_size);
You have to deserialize JSON string on the server side.

blob file edit and upload in angularjs

I am fetching a list of files (which may be of any type) from mysql database and converting them to byte[] and returning all the files of a particular user as an array of files in spring boot.
Now I need to display all the files in the front end and provide an option to edit the file so that the user can remove the already existing file with the new file.
So Whenever a particular file is edited I have to upload the file from front end using angular js.
The Problem is I am getting the files as an array in response.data. I am facing a problem here like, How to edit the a particular file in that array and send the list of files to the backend to store them.I tried to traverse through array of files and store each file as a blob object, but I am not sure of what is the content type of each file as it can be any type of file(.bmp,.pdf,.docx,.tif etc).
Also I am not sure if it is the rightway to do for editing the files, because it may alter the content of the existing file or may change the type of the exixsting file.
So Please suggest me a way to get the file from the database and edit the file if necessary and then push it back to the database.
My controller and services below:-
angular.module("app").service("serviceCalls", function($q, $rootScope, $http) {
this.landOwnerEditProfile = function(email){
var differed = $q.defer();
$rootScope.config.headers.Authorization = sessionStorage.Authorization;
$http
.get($rootScope.URL + "/landownerDetails/"+email+"/", $rootScope.config,{
responseType: 'blob'
})
.then(function(response) {
console.log("coupon service success");
differed.resolve(response);
})
.catch(function(response) {
differed.reject(response);
});
return differed.promise;
};
this.updateLandOwnerProfile = function(details, email) {
var differed = $q.defer();
$rootScope.config.headers.Authorization = sessionStorage.Authorization;
var formdata = new FormData();
// console.log($("#file"));
formdata.append("email", email);
formdata.append("fname", details.user.fname);
formdata.append("lname", details.user.lname);
formdata.append("city", details.user.city);
formdata.append("phone1", details.user.phone1);
formdata.append("phone2", details.user.phone2);
formdata.append("phone3", details.user.phone3);
formdata.append("streetAddressLine1", details.user.streetAddressLine1);
formdata.append("streetAddressLine2", details.user.streetAddressLine2);
formdata.append("stripeApiKey", details.user.stripeApiKey);
formdata.append("zipcode", details.user.zipcode);
formdata.append("businessName", details.user.businessName);
formdata.append("landOwnerEditProfile", true);
// var input_files = document.getElementsByClassName("files");
// for (var i = 0; i < input_files.length; i++) {
// console.log(input_files[i].files);
// for (var file of input_files[i].files) formdata.append("file", file.name);
// }
// formdata.append("file", input_files);
// for (var key of formdata.entries()) {
// console.log(key[0] + ", " + key[1]);
// }
for (var i = 0; i < details.files.length; i++) {
formdata.append("file", details.files[i].file);
}
$http
// .post("http://localhost:8090/", formdata, {
.post($rootScope.URL + "/user/landownerDetails/editProfile/"+email+"/", formdata, $rootScope.config,{
transformRequest: angular.identity,
headers: {
"Content-Type": undefined,
// "Authorization":$rootScope.config.headers.Authorization
}
})
.then(function(response) {
// console.log(response);
if(response.data.status!=true){
throw new Error(" Details Not Updated ");
}
console.log("Details updated success");
differed.resolve(response);
})
.catch(function(response) {
console.log("rejected", response);
differed.reject(response);
});
return differed.promise;
}})
angular
.module("app")
.controller("landOwnerEditProfile", function($state, $scope, $location, serviceCalls, $filter, $stateParams,$timeout) {
$scope.files = [];
serviceCalls.landOwnerEditProfile(sessionStorage.emailId)
.then((response)=>{
console.log(response.data);
let status = response.status;
if(status===200){
let landownerDetails = response.data;
let landowner = landownerDetails.dayleasingusers;
let userdocuments = landownerDetails.userdocuments;// userdocument is an array containing the files
$scope.user = {};
$scope.property={};
$scope.user.fname = landowner.fname;
$scope.user.lname = landowner.lname;
$scope.user.streetAddressLine1 = landowner.address1;
// $scope.user.streetAddressLine2 = landowner.address2 ||'sdasd';
$scope.property.propertyType = landowner.state || 'Alabama';
$scope.user.city = landowner.city;
$scope.user.zipcode = parseInt(landowner.zipCode);
$scope.user.phone1 = !!landowner.phone?parseInt(landowner.phone.substring(0,3)):null;
$scope.user.phone2 = !!landowner.phone?parseInt(landowner.phone.substring(3,6)):null;
$scope.user.phone3 = !!landowner.phone?parseInt(landowner.phone.substring(6)):null;
$scope.user.stripeApiKey = landowner.stripeApiKey;
$scope.user.businessName = landowner.businessName;
$scope.files = [];
for(let doc of userdocuments){
let blob = new Uint8Array(doc.filedata);
$scope.files.push({file:new Blob([blob],{ type:'contentType'})}); //I am not sure of the contentType here.
// $scope.files.push({file:new Blob([doc.filedata],{ type:'multipart/form-data'},doc.filename)});
// $scope.files.push({file:new File([doc.filedata],doc.filename)});
}
}
else{
throw new Error(response.statusText);
}
})
.catch((error)=>{
console.log(error);
})
serviceCalls.updateLandOwnerProfile($scope, sessionStorage.emailId)
.then(function(response) {
console.log(response);
})
.catch(function(error) {
})

Pass on value from inner get statement to out get statement

Hi I am new to angular and wanted to understand promises. I have 2 http get (nested) one inside another. I want to use the value of the inside loop to form a link for the outside get statement as below.
$scope.loadtable = function (task){
var bgUrl = "cloudantlink";
$http.get(bgUrl)
.success(function (response) {
$scope.fileTableData =[];
for(var i =0;i<response.rows.length;i++){
var fileUrl = "cloudantURL";
$http.get(fileUrl, {responseType:'arraybuffer'})
.success(function (response) {
var file = new Blob([response], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
$scope.content = $sce.trustAsResourceUrl(fileURL);
console.log("this is value of promise inside loop", $scope.content);
}).error(function(data){
});
console.log("this is value of promise outside loop",$scope.content);
var fileTableEntry = {
'download' : '' + $scope.content+'',
};
$scope.TableData.push(TableEntry);
}
$scope.loadTable();
}).error(function(data){
});
};
The $scope.content value is always undefined or null outside the second loop. Could someone suggest me a way to pass the value into the first get statement.
A $http.get, or any async operation will just work in the background, and any statement you write after it won't actually wait for this to finish.
If you want to run code after it's finished, you have to use the .then method of the Promise it returns.
In this case, you probably want to wait for all these operations to finish, and then call your $scope.loadTable and related things.
To do this, save the promises returned by the requests and wait for them with $q.all to resolve. Don't forget to add $q to your controller's dependencies.
var fileRequests = [];
for(...) {
fileRequests.push($http.get(fileUrl)
.then(function success(response) { ... return fileUrl; }))
}
$q.all(fileRequests).then(function(fileUrls) { .. $scope.loadTable() })
You also overwrite $scope.content every time, I think you meant to save the URLs in $scope.fileTableData[i].
Full code:
$scope.loadtable = function (task){
var bgUrl = "cloudantlink";
$http.get(bgUrl)
.success(function (response) {
var filePromises =[];
for(var i =0;i<response.rows.length;i++){
var fileUrl = "cloudantURL";
// Saving the promises
filePromises[i] = $http.get(fileUrl, {responseType:'arraybuffer'})
.then(function success(response) {
var file = new Blob([response], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
// This will be the result when the promise is resolved
return $sce.trustAsResourceUrl(fileURL);
}, function error(data) {
});
}
// Waiting for the promises
$q.all(filePromises).then(function(fileUrls)
{
// fileUrls contain the results returned by the success callback
$scope.TableData = fileUrls.map(function(url) {
return { 'download' : '' + url+'', };
})
$scope.loadTable();
})
}).error(function(data){
});

Angular $scope data wont update

Im writing an application which connects to a 3rd party api.
The api uses a auth token system so i have an async node js function which first requests the token and then uses that token to retrieve some data.
The problem is that when the data changes the angualr $scope wont update so the page will show the same data even if an error is thrown in the node js api call.
A little run through the code.
get-salesLead-data.js Has a Async waterfall function which firsts calls the 3rd party rest api using http PUT and returns an auth token. This token is then passed into the second function of the Async water which is then used to make a http GET request to get the sales lead data.
Here is the Node Async api call.
**get-saleLead-data.js**
// app/get-SalesLead-data.js
// modules =================================================
var http = require('http');
var express = require('express')
var async = require('async');
module.exports = function(app) {
Using async to preform async api calls and passing data between them
async.waterfall([
// First function is requesting the auth token
requestToken = function(callback) {
var options = {
"host": "********",
"path": '************'
"method": "PUT",
"headers": {
"Content-Type": "application/json",
}
};
var login = JSON.stringify({
"username": "********",
"password": "********",
"client_ip_address": "********"
});
var req = http.request(options, function(res) {
res.on('data', function(body) {
var body = JSON.parse(body);
var token = body.token;
console.log(token);
callback(null, token);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.write(login);
req.end();
},
// Second function is using the auth token receieved from the first function to get sales lead dat
getData = function(arg1, callback) {
// Geting the sales id from the url and using it in the api request.
app.get('/', function(req, res) {
app.set('salesLeadId', req.query.id);
var token = arg1;
var auth = 'Basic ' + new Buffer('********' + ':' + token).toString('base64');
var path = '****************' + app.get('salesLeadId');
var options = {
"host": "********",
"path": path,
"method": "GET",
"headers": {
"Content-Type": "application/json",
"Authorization": auth
}
};
var data = '';
// Assinging response data to to data
var req = http.request(options, function(res) {
res.on('data', function(chunk) {
data += chunk;
});
// Creating sales lead api so the front end can make requests
res.on('end', function(res) {
var body = JSON.parse(data);
console.log(body);
app.get('/api/salesLead', function(req, res) {
return res.json(body);
$scope.$apply();
});
})
});
req.on('error', function() {
alert('error');
});
res.sendFile('index.html', {
root: '../vpbx/public/views'
});
req.end();
});
}
], function(err, result) {
});
};
Below is the service which accesses /api/salesLead
Creating a function which calls the backend usinga http GET request. This then returns the sales lead data.
**salesLeadService.js**
angular.module('SalesLeadService', []).service('SalesLeadService', function($http, $location, $rootScope) {
var urlBase = '/api/salesLead'
this.getSalesLead = function (data) {
return $http.get(urlBase, data)
};
});
below is the offer controller. This calls the service above and assigns the data to the $scope.salesLead.
**offer.js**
// Form controller
// =============================================================================
angular.module('offerController', []).controller('offerController', function($scope, $http, SalesLeadService, $timeout) {
// GETTING THE DATE-TIME STAMP
$scope.getDate = new Date();
$scope.date = Date();
// CALLING THE FUNCTION FROM THE SALES LEAD SERVICE
SalesLeadService.getSalesLead()
.then(function(response) {
$scope.salesLead = response.data;
$scope.$applyAsync();
});
});
Just a note that i have tried using $scope.$apply but havnt had any luck.
Any help is appreciated
Thanks
Try with object like this way
$scope.object = {salesLead : ''};
$scope.object.salesLead = response.data;
HTML
use {{object.salesLead}}
I think it will work for you
offer.js
angular.module('offerController', []).controller('offerController', function($scope, $http, SalesLeadService, $timeout) {
// GETTING THE DATE-TIME STAMP
$scope.getDate = new Date();
$scope.date = Date();
// CALLING THE FUNCTION FROM THE SALES LEAD SERVICE
$scope.object = {salesLead:''};
SalesLeadService.getSalesLead()
.then(function(response) {
$scope.object.salesLead = response.data;
$scope.$applyAsync();
});
});
I found the issue wasnt to do with the front end but my backend.
The issue was that i had a nested route.
To fix the issue i completely rewrote my routes.

How to Display blob (.pdf) in an AngularJS app

I have been trying to display pdf file which I am getting as a blob from a $http.post response. The pdf must be displayed within the app using <embed src> for example.
I came across a couple of stack posts but somehow my example doesn't seem to work.
JS:
According to this doc, I went on and tried...
$http.post('/postUrlHere',{myParams}).success(function (response) {
var file = new Blob([response], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
$scope.content = fileURL;
});
Now from what I understand, fileURL creates a temporary URL that the blog can use as a reference.
HTML:
<embed src="{{content}}" width="200" height="200"></embed>
I am not sure how to handle this in Angular, the ideal situation would be to (1) assign it to a scope, (2) 'prepare/rebuild' the blob to a pdf (3) pass it to the HTML using <embed> because I want to display it within the app.
I have been researching for more than a day now but somehow I can't seem to understand how this works in Angular... And let's just assume the pdf viewer libraries out there weren't an option.
First of all you need to set the responseType to arraybuffer. This is required if you want to create a blob of your data. See Sending_and_Receiving_Binary_Data. So your code will look like this:
$http.post('/postUrlHere',{myParams}, {responseType:'arraybuffer'})
.success(function (response) {
var file = new Blob([response], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
});
The next part is, you need to use the $sce service to make angular trust your url. This can be done in this way:
$scope.content = $sce.trustAsResourceUrl(fileURL);
Do not forget to inject the $sce service.
If this is all done you can now embed your pdf:
<embed ng-src="{{content}}" style="width:200px;height:200px;"></embed>
I use AngularJS v1.3.4
HTML:
<button ng-click="downloadPdf()" class="btn btn-primary">download PDF</button>
JS controller:
'use strict';
angular.module('xxxxxxxxApp')
.controller('xxxxController', function ($scope, xxxxServicePDF) {
$scope.downloadPdf = function () {
var fileName = "test.pdf";
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
xxxxServicePDF.downloadPdf().then(function (result) {
var file = new Blob([result.data], {type: 'application/pdf'});
var fileURL = window.URL.createObjectURL(file);
a.href = fileURL;
a.download = fileName;
a.click();
});
};
});
JS services:
angular.module('xxxxxxxxApp')
.factory('xxxxServicePDF', function ($http) {
return {
downloadPdf: function () {
return $http.get('api/downloadPDF', { responseType: 'arraybuffer' }).then(function (response) {
return response;
});
}
};
});
Java REST Web Services - Spring MVC:
#RequestMapping(value = "/downloadPDF", method = RequestMethod.GET, produces = "application/pdf")
public ResponseEntity<byte[]> getPDF() {
FileInputStream fileStream;
try {
fileStream = new FileInputStream(new File("C:\\xxxxx\\xxxxxx\\test.pdf"));
byte[] contents = IOUtils.toByteArray(fileStream);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("application/pdf"));
String filename = "test.pdf";
headers.setContentDispositionFormData(filename, filename);
ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(contents, headers, HttpStatus.OK);
return response;
} catch (FileNotFoundException e) {
System.err.println(e);
} catch (IOException e) {
System.err.println(e);
}
return null;
}
michael's suggestions works like a charm for me :)
If you replace $http.post with $http.get, remember that the .get method accepts 2 parameters instead of 3... this is where is wasted my time... ;)
controller:
$http.get('/getdoc/' + $stateParams.id,
{responseType:'arraybuffer'})
.success(function (response) {
var file = new Blob([(response)], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
$scope.content = $sce.trustAsResourceUrl(fileURL);
});
view:
<object ng-show="content" data="{{content}}" type="application/pdf" style="width: 100%; height: 400px;"></object>
I faced difficulties using "window.URL" with Opera Browser as it would result to "undefined". Also, with window.URL, the PDF document never opened in Internet Explorer and Microsoft Edge (it would remain waiting forever). I came up with the following solution that works in IE, Edge, Firefox, Chrome and Opera (have not tested with Safari):
$http.post(postUrl, data, {responseType: 'arraybuffer'})
.success(success).error(failed);
function success(data) {
openPDF(data.data, "myPDFdoc.pdf");
};
function failed(error) {...};
function openPDF(resData, fileName) {
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([resData], { type: 'application/pdf' });
if (ie || oldIE || ieEDGE) {
window.navigator.msSaveBlob(blob, fileName);
}
else {
var reader = new window.FileReader();
reader.onloadend = function () {
window.location.href = reader.result;
};
reader.readAsDataURL(blob);
}
}
Let me know if it helped! :)
Adding responseType to the request that is made from angular is indeed the solution, but for me it didn't work until I've set responseType to blob, not to arrayBuffer. The code is self explanatory:
$http({
method : 'GET',
url : 'api/paperAttachments/download/' + id,
responseType: "blob"
}).then(function successCallback(response) {
console.log(response);
var blob = new Blob([response.data]);
FileSaver.saveAs(blob, getFileNameFromHttpResponse(response));
}, function errorCallback(response) {
});
Most recent answer (for Angular 8+):
this.http.post("your-url",params,{responseType:'arraybuffer' as 'json'}).subscribe(
(res) => {
this.showpdf(res);
}
)};
public Content:SafeResourceUrl;
showpdf(response:ArrayBuffer) {
var file = new Blob([response], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
this.Content = this.sanitizer.bypassSecurityTrustResourceUrl(fileURL);
}
HTML :
<embed [src]="Content" style="width:200px;height:200px;" type="application/pdf" />
I have struggled for the past couple of days trying to download pdfs and images,all I was able to download was simple text files.
Most of the questions have the same components, but it took a while to figure out the right order to make it work.
Thank you #Nikolay Melnikov, your comment/reply to this question was what made it work.
In a nutshell, here is my AngularJS Service backend call:
getDownloadUrl(fileID){
//
//Get the download url of the file
let fullPath = this.paths.downloadServerURL + fileId;
//
// return the file as arraybuffer
return this.$http.get(fullPath, {
headers: {
'Authorization': 'Bearer ' + this.sessionService.getToken()
},
responseType: 'arraybuffer'
});
}
From my controller:
downloadFile(){
myService.getDownloadUrl(idOfTheFile).then( (response) => {
//Create a new blob object
let myBlobObject=new Blob([response.data],{ type:'application/pdf'});
//Ideally the mime type can change based on the file extension
//let myBlobObject=new Blob([response.data],{ type: mimeType});
var url = window.URL || window.webkitURL
var fileURL = url.createObjectURL(myBlobObject);
var downloadLink = angular.element('<a></a>');
downloadLink.attr('href',fileURL);
downloadLink.attr('download',this.myFilesObj[documentId].name);
downloadLink.attr('target','_self');
downloadLink[0].click();//call click function
url.revokeObjectURL(fileURL);//revoke the object from URL
});
}
A suggestion of code that I just used in my project using AngularJS v1.7.2
$http.get('LabelsPDF?ids=' + ids, { responseType: 'arraybuffer' })
.then(function (response) {
var file = new Blob([response.data], { type: 'application/pdf' });
var fileURL = URL.createObjectURL(file);
$scope.ContentPDF = $sce.trustAsResourceUrl(fileURL);
});
<embed ng-src="{{ContentPDF}}" type="application/pdf" class="col-xs-12" style="height:100px; text-align:center;" />

Resources