2

We are displaying the details of the user in an HTML page and apart from other details it contains a link item in it, which retrieves the image stored as BLOB of the user from the database. Our angular Service is written, Click on the link item opens (which is actually the filename of that image in the database) up a browser window displaying the Image. Both storing and retrieving the image works fine Now our requirement is to just load on first load of HTML page the Image as a preview.

Angular service is like

getDownloadDoc: function(empId) {

  return $http.get(contextPath1 + "/PdfServletDoc?documentID=" + empId + "", {
    responseType: 'arraybuffer'
  }).then(function(response) {
    var data = response.data;
    var file = new Blob([data], {
      type: 'image/jpeg'
    });
    var fileURL = URL.createObjectURL(file);
    window.open(fileURL);
    return response;
  });
},

I am new to AngularJs, if could only get the resources or documentations to look for this. That will be helpful

Priya
  • 1,522
  • 1
  • 14
  • 31
Mozif Beigh
  • 109
  • 1
  • 1
  • 8
  • 2
    Don't generate Blob instead do arraybuffer to base64; then adding data:image/jpeg;base64,responsestring will give you proper image when you will give that as a src to image tag. Ref: https://stackoverflow.com/questions/9267899/arraybuffer-to-base64-encoded-string . For download just use the same respponse string with data:application/octate-stream;base64,responsestring – Priya Jul 12 '17 at 09:12

2 Answers2

4

I am assuming that your image is downloaded perfectly and fileURL contains path to image, then you can do but first pass fileURL to controller and in your template file:

<img ng-src={{fileURL}}></img>

In Controller:

you will call your angular service like this:

function yourImageSuccessHandler(fileUrl, options) {
            $scope.fileUrl = fileUrl; // now you will have fileUrl in 
                                      // controller
        }
        yourService.getDownloadDoc(empId, {
            successCallBack: yourImageSuccessHandler
        });

In Service

getDownloadDoc : function(empId, options) {

    return $http.get(contextPath1+"/PdfServletDoc?documentID="+empId+"", {
                        responseType : 'arraybuffer'
                    }

            ).success(function(data) {
                var file = new Blob([ data ], {
                    type : 'image/jpeg'
                });
                var fileURL = URL.createObjectURL(file);

                if(options && options.successCallBack) {
                    return options.successCallBack(fileURL, {});
                }
            });
        },
Wasif Khan
  • 956
  • 7
  • 25
  • Yes the image is getting downloaded perfectly and I suppose PathURL is also correct then. Can I just simply just pass this fileURL variable from service to controller..?? ...Because I am doing that but the Image is not getting loaded in img tag. – Mozif Beigh Jul 12 '17 at 10:04
  • @MozifBeigh you can pass variables in callbacks. – Wasif Khan Jul 12 '17 at 10:18
  • If am passing the variable back to controller the console.log (fileURL) just contains the Status code (200) not the URL. In service the URL is correctly displaying blob:http://localhost:8080/405f0b1d-fcb7-42a8-860e-2d04f033f01b. – Mozif Beigh Jul 12 '17 at 10:30
  • Yes. Its working....URL is getting passed correctly but image still not getting rendered on HTML page. – Mozif Beigh Jul 12 '17 at 11:58
  • comment your html code and variable in which imageUrl is stored – Wasif Khan Jul 12 '17 at 12:16
  • {{ fileName}} On click of filename which gets loaded with first page load itself we are hitting downloaddoc() in controller. In developer tools after hitting service the img src is pointing to blank/no URL. – Mozif Beigh Jul 13 '17 at 07:04
  • Now, I am just returning whole response from Service and creating file URL in controller itself. That way the img src is pointing to the URL but it is showing image src unsafe blob and giving just small image icon. I tried to add $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension):/); $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension):/); But still facing same issue – Mozif Beigh Jul 13 '17 at 08:04
  • Okay, @MozifBeigh the issue now is that you are having blob: prefix on your imageUrl right? – Wasif Khan Jul 13 '17 at 09:32
  • Yes Error :unsafe:blob:http://localhost:8080/dd7aab75-121e-4b42-a739-70f4a8c13955 – Mozif Beigh Jul 13 '17 at 09:55
  • This is your solution https://stackoverflow.com/questions/15606751/angular-changes-urls-to-unsafe-in-extension-page ask me if you dont get it – Wasif Khan Jul 13 '17 at 09:59
  • did u add blob in that regex like this? $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|file|blob):|data:image\//); – Wasif Khan Jul 13 '17 at 10:28
  • I thought blob was added. but was missing the image is coming now correctly.Thanks for your responses. – Mozif Beigh Jul 13 '17 at 11:32
3

Instead of creating a dataURL from an arraybuffer, set the responseType to 'blob'.

To display the blob as an image with the ng-src directive, convert the blob to a data URL with URL.createObjectURL():

  var config = {
      responseType: 'blob'
  };
  $http.get(url,config)
    .then(function(response) {
      vm.blob = response.data;
      vm.dataURL = URL.createObjectURL(vm.blob);
  });
  <h1>Blob image demo</h1>
  <img ng-src="{{dataURL}}">

The DEMO

angular.module("app",[])
.run(function($rootScope, $http) {
  var vm = $rootScope;
  var config = {responseType: 'blob'};
  var url = "https://i.imgur.com/YnjcO.jpg"
  $http.get(url,config)
    .then(function(response) {
      vm.blob = response.data;
      vm.dataURL = URL.createObjectURL(vm.blob);
  });
})
<script src="//unpkg.com/angular/angular.js"></script>
  <body ng-app=app>
    <h1>Blob image demo</h1>
    <img ng-src="{{dataURL}}" style="width: 200px">
  </body>

Update

the img src is pointing to the URL but it is showing image src unsafe blob and giving just small image icon. I tried to add

$compileProvider.aHrefSanitizationWhitelist(
     /^\s*(https?|ftp‌​‌​|mailto|chrome-ext‌​en‌​sion):/
  ); 
$compileProvider.imgSrcSanitizationWhitelist(
    /^\s*(https?|f‌‌​​tp|mailto|chrome-ex‌​t‌​ension):/
);  

But still facing same issue

The use AngularJS V1.6 or set the default sanitation settings to:

var aHrefSanitizationWhitelist = 
                 /^\s*(https?|ftp|mailto|tel|file):/;
var imgSrcSanitizationWhitelist = 
                 /^\s*((https?|ftp|file|blob):|data:image\/)/;

For more information,

georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • the img src is pointing to the URL but it is showing image src unsafe blob and giving just small image icon. I tried to add $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp‌​|mailto|chrome-exten‌​sion):/); $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|f‌​tp|mailto|chrome-ext‌​ension):/); But still facing same issue – Mozif Beigh Jul 13 '17 at 08:12
  • What version of AngularJS are you using? It works with V1.6 in the above Demo. – georgeawg Jul 13 '17 at 10:49
  • this solution sometimes works, rather than setting response type blob I think array buffer solves the problem as mentioned by @wasif – ngLover Feb 02 '18 at 10:58