call javascript function outside of scope on ng-click

All we need is an easy explanation of the problem, so here it is.

I have a javascript library with a bunch of useful functions that I make use of across my website that does various things.

I know that I cannot access these functions from an ng-click, because the functions are outside of scope.

Is there a way to access them without having to declare a scope function that just makes a call to the function in the library?

Here is a jsfiddle with an example. I would like to know if there’s a way to make the second link work.
This is simply because I do not like the idea of defining a function that will simply call another function. e.g.

HTML:

<div ng-click="doSomething()">Click Me (Working)</div>
<div ng-click="doSomethingElse()">Click Me (Not Working)</div>

Controller JS:

$scope.doSomething = function () {
    doSomethingElse();
};

External Library JS:

function doSomethingElse() {
    alert("SomethingElse");
}

<——-UPDATE——->

Thanks for the creative responses guys!
Vinay K’s answer is the easiest and most obvious, but I decided to go with Ron E’s answer.
The reason is that I already have a global module with a collection of reusable directives and that would make it easier and cleaner to implement in my HTML. Also because I sometimes use more than one function from the library and then would have to chain them in the onclick:

onlick="func1(); func2(); func3();"

Where a directive is just cleaner and I can call as many functions as I like while doing other stuff as well.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

ng-click expression (or any other expression in angular) will be evaluated in the context of the scope.

As doSomethingElse is not defined on scope it will not work.

Use onclick instead of ng-click

<div ng-click="doSomething()">Click Me</div>
<div onclick="doSomethingElse()">Click Me </div>

Method 2

You could use a directive, here is an example:

// in your JS source
angular.directive('something', [function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('click', function() {
                alert('yup');
            });
        }
    };
}]);

// in your HTML file
<button type="button" something>Click Me!</button>

This allows you to reuse your various code chunks / functions across your entire project pretty easily.

Method 3

Hi İf you have defined javascript function you can use old js functions and Angular js together

Example:

<div ng-click="doSomething()" class="myBtn"=>Click Me (Working)</div>
//JQuery Lib must be included your project
$(document).on('click','.btn',function(){
    eval($(this).attr('ng-click'));
});
function doSomething(){
//Bla Blo Blu Bli
}

Thank for reading

Method 4

If your library is available globally (for example, on the window object) you could write a method in your rootScope that accepts the function name as a parameter. Guaranteed this isn’t the most orthodox way to do things in Angular but it will eliminate the need to add all these extra methods in all of your scopes. Here’s a rough example:

In your app.run method you could add something like this:

$rootScope.callWindowMethod = function(methodName, parameter) {
  if(typeof window[methodName] !== 'function') {
    console.log('could not find ', methodName, ' function');
    return;
  }
  return window[methodName](parameter);
};

Then in your view you could do something like this:

<button ng-click="$root.callWindowMethod('alert','Hey there!')">Click Me</button>

You could get even fancier and pass in an arbitrary number of parameters to your function as well as have the function name contain dots for methods that are nested in other objects and split those up. This should at least get you started.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply