Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular External js library calling Document.Ready

Using a 3rd party js library in my .net core asp angular app. The library applies it's logic in the $(document).ready method. So im having an issue where the libraries aren't applying correctly on a angular route change because the $(document).ready method doesn't fire.

I've referenced the external js library in my angular-cli scripts section.

I opened the 3rd party js file and added a method to it that calls the same logic that they are calling in the document ready. Im just struggling to find a way to call that method from my angular typescript component.

I've created a simple cut down js file to test it out and simplify the problem. I have the following Tester.js which is referenced in my -angular-cli.json under the scripts tag:

(function ($) {
    "use strict";

    $(document).ready(function () {        
        CallMe();
    });

    function CallMe(){
         console.log('HEY I GOT CALLED');
    }

 })(jQuery);

Im wanting to be able to call the CallMe() method when from inside a ts component file. The CallMe() gets fired once as expected on the document.ready event but I need to work out how to call this ad hoc from within my ts scripts.

Any ideas?

like image 283
Matt Avatar asked Jun 29 '18 05:06

Matt


1 Answers

Step 1

Check if the external library is available on npm. If so you may be able to import the desired function rather than altering a vendored file.

For example, it may provide an API such that:
YourTsComponent.ts

const CallMe = require('library').CallMe
// or
import { CallMe } from 'library'

// on route change
CallMe()

If something like that is available, great, otherwise...

Step 2

Confirm your theory with a global (attach CallMe to window temporarily). If your theory is correct, you should be able to get the desired behavior by calling this global variable on route change.

Tester.js

(function($) {
  "use strict";

  $(document).ready(function() {
    CallMe();
  });

  function CallMe() {
    console.log('HEY I GOT CALLED');
  }

  // TODO - remove (test only)
  window._CallMe = CallMe
})(jQuery);

YourTsComponent.ts

// on route change
window._CallMe()

If that doesn't work, you must reevaluate your theory.

but if it does ...

Step 3

Convert the vendored library to a module that can be consumed by your app. Your mileage may vary based on what (if any) module system you are using. For example, if you are using require.js:

Tester.js

(function(factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD
    define(['jquery'], factory);
  } else if (typeof exports === 'object') {
    // CommonJS
    factory(require('jquery'));
  } else {
    // Browser globals
    factory(jQuery);
  }
}(function($) {
  "use strict";

  function CallMe() {
    console.log('HEY I GOT CALLED');
  }

  $(document).ready(function() {
    CallMe();
  });

  return CallMe
}));

YourTsComponent.ts

const CallMe = require('/path/to/tester.js')

// on route change
CallMe()

If you're not keen on re-writing a vendored library

You may consider overriding .ready's default behavior so that it may be retriggered. There Are a few answers here if you want to go this route, but be warned, overriding default jQuery behavior is probably much more error prone than editing a single vendored file.

like image 168
Damon Avatar answered Nov 02 '22 23:11

Damon