unable to show the pdf file when the path and filename is loaded dynamically

1.5k views Asked by At

I am working on angularjs and java application. The below html code is used to open pdf file in browser.Issue is PDF is not getting opened when the value for the data attribute is passed dynamically as shown below.

<div ng-controller="myPDFFileController">
{{pdfName}} <!-- /resources/myFiles/test1.pdf -->
<object data="{{pdfName}}" type="application/pdf" width="100%" height="100%"> 
<iframe src="{{pdfName}}" width="100%" height="100%" style="border: none;">
    This browser does not support PDFs. Please download the PDF to view it: 
</iframe>
</object>

js code:

    app.controller('myPDFFileController', function ($scope,MyService) {
    $scope.getPDFPathFileName = function () {
    MyService.getPDF().then(
    function (response) {
    $scope.pdfName = "/resources/myFiles/"+response;
    },
    function (errResponse) {
    $rootScope.showError("Internal error" + errResponse);
    });
    }
    $scope.getPDFPathFileName();
    });
    //service call
    myService.getPDF = function(){
     var Url = myURL+'/filesDataLink/getPDF.form';
    $http.get(repUrl)
    .then(
    function (response) {
       //return response
    }
   //return statement
    }

java controller:

@RequestMapping(value = "/getPDF", method = RequestMethod.GET,produces="text/plain")
public @ResponseBody String getPDF(HttpServletRequest request) throws Exception {
//code to creae a pdf file and return the filename 
String filename = "test1";
File f = new File(filename);
//logic to generate pdf file with data
return filename;
}
}

Exception noticed in browser console:

Failed to load resource: the server responded with a status of 404 () :8080/%7B%7BpdfName%7D%7D

Please advice how to pass the filename dynamically at runtime and make the PDF open on the browser. The below code works when i gave the filename in the html code itself instead of loading dynamically.

Working html code when the filename is assigned to data attribute:

<object data="/resources/myFiles/test1.pdf" type="application/pdf" width="100%" height="100%">
<iframe src="/resources/myFiles/test1.pdf" width="100%" height="100%" style="border: none;">
This browser does not support PDFs. Please download the PDF to view it: 
</iframe>
</object>

--EDIT-- Now I can see the pdf image in webpage both IE and chrome, but issue is IE is showing an alert before the pdf is loaded. Below is the alert box image appearing in IE when I load the page ,after I close the alert box the pdf is shown. No errors are shown in console. enter image description here

2

There are 2 answers

4
Raphael On

I had the same issue in my project.See whether it helps.

HTML CODE

<object ng-if="!IEBrowser" data="{{content}}" type="application/pdf" style="width: 100%; height: 1200px;overflow-y: hidden; cursor:pointer;"></object> 
<iframe ng-if="IEBrowser" id ="pdfIframe" ></iframe>

Controller

 $scope.caseid =$rootScope.finalCeilingValue.caseId;

    $http.get(appConstant.selfDomainName+appConstant.downloadCreditPaper+"?"+"caseid="+$scope.caseid, {responseType: 'arraybuffer'})

          .success(function (data) {
             /* if(data){
          var file = new Blob([data], {type: 'application/pdf'});

            var fileURL = URL.createObjectURL(file);

        //   $scope.content = fileURL;
              }*/

                        if($scope.caseid != null && $scope.caseid != ''){
                                     $scope.content =  appConstant.selfDomainName+appConstant.downloadCreditPaper+"?"+"caseid="+$scope.caseid;
                             if(window.navigator.msSaveOrOpenBlob){
                                     $scope.IEBrowser = true;
                                      $timeout(function() {
                                                 document.querySelector('#pdfIframe').setAttribute('src',$scope.content);
                                                  }, 0);
                             } else {
                                 $scope.IEBrowser = false;
                             }
            ////        $scope.content = appConstant.selfDomainName+appConstant.downloadCreditPaper+"?"+"caseid="+$scope.caseid;


                        } 
        else{ $scope.message.code = "Unable to load";
                                   $scope.message.color = genericAPIFactory.amber;
                                   $scope.$emit("approvalFlowWarning",$scope.message);
                                     }
          }).finally(function() {
            $scope.loading = false;
          })
4
Rabbi Shuki Gur On

UPDATE

Just noticed that there is a better answer in SO already. Check out the link: https://stackoverflow.com/a/21752504/5739073

Original Answer.

The reason it is not working is because you are using the src attribute instead of the ng-src attribute.

The difference between the two is, that when you use the ng-src it waits until there is a value to that scope variable before adding it to the DOM, and so the HTML thinks it was hardcoded.