Invoke AngularJS from Outside AngularJS

Rajnilari2015
Posted by in AngularJS category on for Beginner level | Points: 250 | Views : 407 red flag

Sometime we may have a requirement to invoke an AngularJS function from Non-AngularJS stuff. In this article, we will look into how to do so with a simple example. We will build a simple Calculator for our demonstration purpose.


 Download source code for Invoke AngularJS from Outside AngularJS

Introduction

Sometime we may have a requirement to invoke an AngularJS function from Non-AngularJS stuff. In this article, we will look into how to do so with a simple example. We will build a simple Calculator for our demonstration purpose.

Straight To experiment

Let us first make a simple design by using the below code

<table border="1" width="40%" bgcolor="yellow">
		<tbody><tr>
			<td>
				<table>
					<tbody><tr>
						<td>Enter First Number :     <input type="text" id="txtNum1"></td>
					</tr>
					<tr>
						<td>Enter Second Number : <input type="text" id="txtNum2"></td>
					</tr>
					<tr>
						<td>
							<input type="button" id="btnAdd" value="Add">   
							<input type="button" id="btnSub" value="Sub">   
							<input type="button" id="btnMul" value="Multiply">   
							<input type="button" id="btnDiv" value="Divide">
						</td>
					</tr>
				</tbody></table>
			</td>
			<td>
				The result is : <div id="divResult"></div>
				
			</td>
		</tr>		
	</tbody></table>

This will result into

Our objective is to invoke the Calculator function written in AngularJs from vanilla JS function.

In order to do so,let us first create a function as under

<!-- vanilla javascript function-->
function Calculate(operator){	

	var num1 = document.getElementById('txtNum1').value;
	var num2 = document.getElementById('txtNum2').value;			
}

Next create a controller and write a function to perform the Calculator operation as under.

<!-- AngularJs function-->
angular.module('myCalciApp', [])
    	.controller('myCalciCtrl', function ($scope) {
		$scope.calciFn = function (num1,num2,operator) {

			document.getElementById('divResult').innerHTML =

						 operator == "+" ? num1 - (-num2) :
						 operator == "-" ? num1 - num2 :
						 operator == "*" ? num1 * num2 :
						 Math.round((num1 / num2) * 100) / 100; 
		};
});

The calciFn takes three arguments viz. the two numbers and an operator for performing it's operation and put's the result back to the divResult div.

Now we need to find a mechanism to talk between the vanilla javascript function (Calculate) and AngularJs function (calciFn). For this we need angular.element. It wraps a raw DOM element or HTML string as a jQuery element. If jQuery is available, angular.element is an alias for the jQuery function. If jQuery is not available, angular.element delegates to Angular's built-in subset of jQuery, called "jQuery lite" or jqLite.

Now let's modify the vanilla javascript function (Calculate) as under.

<!-- vanilla javascript function-->
function Calculate(operator){	

	var num1 = document.getElementById('txtNum1').value;
	var num2 = document.getElementById('txtNum2').value;
	var result = document.getElementById('divResult');	
	angular.element(result).scope().calciFn(num1,num2,operator);	
}

For accessing the scope outside of AngularJS, we are using angular.element(elementID).scope(). Once we have the AngularJS scope, we can now invoke the AngularJs function (calciFn).

One small change that needs to be incorporated is that, we need to set the ng-app and ng-controller to the div as under

<div id="divResult" ng-app="myCalciApp" ng-controller="myCalciCtrl" class="ng-scope">
</div>

The complete program is as under

<script data-require="angular.js@1.4.0-beta.6" data-semver="1.4.0-beta.6" src="https://code.angularjs.org/1.4.0-beta.6/angular.js"></script>  
    
	<script type="text/javascript">

	<!-- AngularJs function-->
	angular.module('myCalciApp', [])
    		.controller('myCalciCtrl', function ($scope) {
    		$scope.calciFn = function (num1,num2,operator) {

    			document.getElementById('divResult').innerHTML =

    						 operator == "+" ? num1 - (-num2) :
    						 operator == "-" ? num1 - num2 :
    						 operator == "*" ? num1 * num2 :
    						 Math.round((num1 / num2) * 100) / 100; 
    		};
	});

    <!-- vanilla javascript function-->
	function Calculate(operator){	

		var num1 = document.getElementById('txtNum1').value;
		var num2 = document.getElementById('txtNum2').value;
		var result = document.getElementById('divResult');		
		angular.element(result).scope().calciFn(num1,num2,operator);	
		
	}
</script>


	<center>
		<h2>Calculator Demo for invoking AngularJS from Outside AngularJS  - RNA Team</h2>
		<table border="1" width="40%" bgcolor="yellow">
			<tbody><tr>
				<td>
					<table>
						<tbody><tr>
							<td>Enter First Number :     <input type="text" id="txtNum1"></td>
						</tr>
						<tr>
							<td>Enter Second Number : <input type="text" id="txtNum2"></td>
						</tr>
						<tr>
							<td>
								<input type="button" id="btnAdd" value="Add" onclick="Calculate('+')">   
								<input type="button" id="btnSub" value="Sub" onclick="Calculate('-')">   
								<input type="button" id="btnMul" value="Multiply" onclick="Calculate('*')">   
								<input type="button" id="btnDiv" value="Divide" onclick="Calculate('/')">
							</td>
						</tr>
					</tbody></table>
				</td>
				<td>
					The result is : <div id="divResult" ng-app="myCalciApp" ng-controller="myCalciCtrl"></div>
					
				</td>
			</tr>		
		</tbody></table>
	</center>

The result for subtraction is shown below

Instead of referring the ElementId, we can also refer through the controller name as under

<!-- vanilla javascript function-->
	function Calculate(operator){	

		var num1 = document.getElementById('txtNum1').value;
		var num2 = document.getElementById('txtNum2').value;
		angular.element('[ng-controller=myCalciCtrl]').scope().calciFn(num1,num2,operator);
	}

We are using JQuery selector here for inspecting the controller scope. But in this case, we need to have a reference of JQuery. The complete code for the same is provided below

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  	<script data-require="angular.js@1.4.0-beta.6" data-semver="1.4.0-beta.6" src="https://code.angularjs.org/1.4.0-beta.6/angular.js"></script>  
    
	<script type="text/javascript">

	<!-- AngularJs function-->
	angular.module('myCalciApp', [])
    		.controller('myCalciCtrl', function ($scope) {
    		$scope.calciFn = function (num1,num2,operator) {

    			document.getElementById('divResult').innerHTML =

    						 operator == "+" ? num1 - (-num2) :
    						 operator == "-" ? num1 - num2 :
    						 operator == "*" ? num1 * num2 :
    						 Math.round((num1 / num2) * 100) / 100; 
    		};
	});

    <!-- vanilla javascript function-->
	function Calculate(operator){	

		var num1 = document.getElementById('txtNum1').value;
		var num2 = document.getElementById('txtNum2').value;		
		angular.element('[ng-controller=myCalciCtrl]').scope().calciFn(num1,num2,operator);
	}
</script>


	<center>
		<h2>Calculator Demo for invoking AngularJS from Outside AngularJS  - RNA Team</h2>
		<table border="1" width="40%" bgcolor="yellow">
			<tbody><tr>
				<td>
					<table>
						<tbody><tr>
							<td>Enter First Number :     <input type="text" id="txtNum1"></td>
						</tr>
						<tr>
							<td>Enter Second Number : <input type="text" id="txtNum2"></td>
						</tr>
						<tr>
							<td>
								<input type="button" id="btnAdd" value="Add" onclick="Calculate('+')">   
								<input type="button" id="btnSub" value="Sub" onclick="Calculate('-')">   
								<input type="button" id="btnMul" value="Multiply" onclick="Calculate('*')">   
								<input type="button" id="btnDiv" value="Divide" onclick="Calculate('/')">
							</td>
						</tr>
					</tbody></table>
				</td>
				<td>
					The result is : <div id="divResult" ng-app="myCalciApp" ng-controller="myCalciCtrl"></div>
					
				</td>
			</tr>		
		</tbody></table>
	</center>

Reference

angular.element

Conclusion

In this article we have learnt how to invoke AngularJS from Outside AngularJS. Hope this will be helpful. Thanks for reading. Zipped file attached.

Page copy protected against web site content infringement by Copyscape

About the Author

Rajnilari2015
Full Name: Niladri Biswas (RNA Team)
Member Level: Platinum
Member Status: Member,Microsoft_MVP,MVP
Member Since: 3/17/2015 2:41:06 AM
Country: India
-- Thanks & Regards, RNA Team


Login to vote for this post.

Comments or Responses

Login to post response

Comment using Facebook(Author doesn't get notification)