cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - New to the community? Learn how to post a question and get help from PTC and industry experts! X

How to call tml3dRenderer from external .js file

Roccobarocco
12-Amethyst

How to call tml3dRenderer from external .js file

Hello everyone, I've downloaded a sample Hololens project with PDF reader included (via external library pdf.js) and it works fine both in Hololens and preview.

Other than the external library there's also some code in Home.js that initialize and handles the reader variable, I want to move this code to an external file too for legibility purpose.

The problem occurs when code try to execute a line where 'tml3dRenderer' is in use:

"PDFreader.js:181 Uncaught (in promise) ReferenceError: tml3dRenderer is not defined "

there's a particular way to refer interal components (like tml3dRenderer is) from external files that I'm missing?
Once external .js is appendend to HTML document.head shouldn't it be recalled like the code is wrote directly in Home.js?

I'm relatively new to angular/web js development and after some google searches I can't find anything useful,

p.s. can't retrieve where I've downloaded the project so I've attached here a copy

ACCEPTED SOLUTION

Accepted Solutions

I tested this with the simple approach mentioned in the previous post and it seems to work. OK possibly it is  not the best solution but it work. In the code I tried  simple to ensure that PDF js is loaded  and therefore I used timeout of 1 sec. OK possibly it will work with smaller time interval or in some then block. Attached it to the project

View solution in original post

7 REPLIES 7

Hi @Roccobarocco ,

so possibly you can define a local variable in your code what you can later set via setter function something like this

 

//in your code
var my3dRenderer= undefined
function setMyVariable(tmlRender)
{my3dRenderer= tmlRender;}
//======
// then in the module call e.g. 
my3dRenderer.setTranslation('model-1-/0/1, 1.0, 0.0,  0.5 ); 
//etc

 

then load the code:

 

//---------------Loading the API----------------------- 
$scope.asyncLoadScript = function (fname) {
  return new Promise((resolve, reject) => {
    if(fname) { var head = document.head || document.getElementsByTagName('head')[0],
                script = document.createElement('script');
      script.async = true; script.onload = resolve;
      script.onerror = reject; script.type = 'text/javascript';
      script.src=fname;  head.appendChild(script); } });}
//$scope.asyncLoadScript("app/resources/Uploaded/test.js")
var mathe =undefined;
//////////////////////////////////////////
$scope.pdfModuleLoad = function() {
console.log("pdfModuleLoad started"); 
var pdf =undefined;
$scope.asyncLoadScript("app/resources/Uploaded/MyPdfFunc.js").then(
 function() { console.log("myMathFunc was loaded successfully") ;TESTLOAD();
//and later try to pass the tml3DRenderer to the module
$timeout( ()=> {setMyVariable(tml3dRenderer)},300)
}, 
     function() { console.log("error for when loading myPdfFunc.js module");} );
}
//

$scope.pdfModuleLoad(); //LOAD dhere the myMathFunc.js for 

 

 So far I know such construct will not work if you will try to call this js in  a second thread /according in https://www.w3schools.com/html/html5_webworkers.asp and https://medium.com/jspoint/achieving-parallelism-in-javascript-using-web-workers-8f921f2d26db

I downloaded your project but after fast check in preview - there were no any errors and pdf was displayed fine. What should we change to reproduce the issue. Thanks

Hi @RolandRaytchev  and thanks for your fast reply.
I plan to use this PDF reader in more complex experiences than this one, so my objective is to move code from Home.js in external ,js and call from there.

 

I've already tried to copy&paste the code in external .js file (PDFreader.js) and import it at the beginnig of the experience with:

 

$scope.asyncLoadScript('app/resources/Uploaded/PDFreader.js')

 

 everything seems ok, the import log 'success' but when i call the loadPDF function that use the tml3dRender line of code, that's when the error comes out.



 Trying to better explain, that's what is in my Home.js now:

// *****************  Asynch - createElement('script'/'link')  *****************
$scope.app.loadScriptAsync = function (fname) {
  
  var ext =/^.+\.([^.]+)$/.exec(fname);  
  if(ext == null) {console.error("error checking extension!");return;}
  return new Promise((resolve, reject) => {    
    var head
    var script, link    
    if(ext[1]=='js') { 
      console.info("lib:"+ext[0]+" is javascript");      
      head = document.head || document.getElementsByTagName('head')[0];
      script = document.createElement('script');
      script.async = true; 
      script.onload = resolve;
      script.onerror = reject; 
      script.type = 'text/javascript';
      script.src=fname;  head.appendChild(script); 
    }//if 
    else if(ext[1]=='css') { 
      console.info("lib:"+ext[0]+" is style CSS");      
      head = document.head || document.getElementsByTagName('head')[0];
      link = document.createElement('link');
      link.async = true; 
      link.onload = resolve;
      link.onerror = reject; 
      link.type = 'text/css';link.rel = 'stylesheet';
      link.href = fname;                   
      link.media = 'all';
      head.appendChild(link);
    }//else
  });//promise
}

// -----------------ON: BEFORE ENTER------------------
/* Triggered before entering the View  
 ----------------------------------------------------*/
$scope.$on('$ionicView.beforeEnter', function() {
  console.warn('---- ON: BEFORE ENTER VIEW ----')  
  $scope.app.loadScriptAsync('app/resources/Uploaded/PDFreader.js')
})

// -----------------ON: AFTER ENTER-------------------
/* Triggered immediately after entering the View  
 ----------------------------------------------------*/
$scope.$on('$ionicView.afterEnter', function() {
  console.warn('---- ON: AFTER ENTER VIEW ----')  
  $timeout( () => {
    // load pdfjs
    var script = document.createElement('script');    
    script.onload = function () {
      console.log('script.onload')
      $scope.checklistPdfPopup = new PdfRendererPopup($scope.view.wdg['pdfImage'], {
        pdfImage: $scope.view.wdg['pdfImage'],
        pdfNextPageIcon: $scope.view.wdg['pdfNextPageIcon'],
        pdfPrevPageIcon: $scope.view.wdg['pdfPrevPageIcon'],
      }, 1);
    };    
    script.src="app/components/pdf.min.js";
    document.head.appendChild(script);
  }, 5000)
})

$scope.showPdfPopup = function () {
  $scope.checklistPdfPopup.loadPdf("app/resources/Uploaded/license_agree.pdf");
  $scope.checklistPdfPopup.show();
};

$scope.hidePdfPopup = function () {
    $scope.checklistPdfPopup.hide();
};

 Everything else is now in external PDFreader.js in app/resources/Uploaded folder.
When in scene, i click the blue image to show PDF, that's when console return: 
tml3dRenderer console error.jpg

 

Attached the project with the external file

I tested this with the simple approach mentioned in the previous post and it seems to work. OK possibly it is  not the best solution but it work. In the code I tried  simple to ensure that PDF js is loaded  and therefore I used timeout of 1 sec. OK possibly it will work with smaller time interval or in some then block. Attached it to the project

Your solution does the trick!
@RolandRaytchev  thank you very much!

I've edited my post, I missed that in external .js you've defined the setTml3D() function, so no setter are involved:

  var thisTml3D = undefined
  function setTml3D(tml3D){thisTml3D=tml3D;}

 

Hi @Roccobarocco ,

I am happy to hear that this was helpful. About the function setTml3D (name is not relevant ) - I simple added to the loading script PDFreader.js the following code:

var thisTml3D=undefined
function setTml3D(tml3D){thisTml3D=tml3D;}
....
....
// and later  line 183replaced the tml3DRender variable:
// tml3dRenderer.setTexture(this.widgets.pdfImage.widgetName, this.canvas.toDataURL());
//replace to		
thisTml3D.setTexture(this.widgets.pdfImage.widgetName, this.canvas.toDataURL());

 

Announcements

Top Tags