I'm trying to display a div if an object is non-empty. Using this answer, Im trying to use angular.equals to check emptyness, but its not behaving as expected
var test = angular.module('test',[]);
test.controller('testCtrl', ['$scope', function($scope){
$scope.foo={};
$scope.bar="bam"
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test">
<div ng-controller="testCtrl">
<div ng-show="!angular.equals(foo,{})">{{bar}}</div>
</div>
</div>
The expectation here is that the value of bar will only show if foo is not equal to an empty object. However, foo is clearly set to {} and yet bar still shows.
If you want to access the angular object from templates or expressions, you have to make it available on the scope of where you want to use it. In this case you can put it on the testCtrl's scope.
var test = angular.module('test',[]);
test.controller('testCtrl', ['$scope', function($scope){
$scope.angular = angular;
$scope.foo={};
$scope.bar="bam"
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test">
<div ng-controller="testCtrl">
<div ng-show="!angular.equals(foo,{})">{{bar}}</div>
</div>
</div>
I generally put utility objects on $rootScope, so they're available from everywhere.
A cleaner way would be to only add the angular equals method to the $scope:
var test = angular.module('test',[]);
test.controller('testCtrl', ['$scope', function($scope){
$scope.angularEquals = angular.equals;
}
Then you can use the equals method in the template, like:
<div ng-show="!angularEquals(foo,{})">{{bar}}</div>
Your view is looking for a function on the scope, and $scope.angular.equals does not exist. You need to write one like this:
var test = angular.module('test', []);
test.controller('testCtrl', ['$scope',
function($scope) {
$scope.foo = {};
$scope.bar = "bam";
$scope.isEmpty = function(obj) {
return angular.equals(obj,{});
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test">
<div ng-controller="testCtrl">
<div ng-hide="isEmpty(foo)">{{bar}}</div>
</div>
</div>
Angular functions can't be used inline, AFAIK.
You could do the equal check with a function inside the controller instead and return the result.
Related
I'm new to angular and little bit confused with it. So basically I created a simple button and i want to run function foo() whitch assigns variable var one = 1; to $scope and outputs it in <p>{{one}}<p> every time its clicked like in live typing but this seems not working. Please provide me a solution to this.
<html ng-app="app">
<!-- Body tag augmented with ngController directive -->
<body ng-controller="myController">
<input type="text" ng-model="name">
<p>{{name}}</p>
<p>{{one}}</p>
<button ng-click="foo()">1</button>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="controller.js"></script>
</body>
</html>
controller:
var app = angular.module('app',[]);
app.controller('myController', ['$scope',function($scope){
var one = 1;
$scope.name = name;
function foo(){
return $scope.one = one;
}
}]);
function foo() dont exist in $scope your controller "myController"
if you declaration:
$scope.foo = function(){}
in your controller, then this work for you
when you are calling controller function from the html, controller function should be scope. Other wise ng-click directive doesn't recognize the function.
same concept goes to binding variable to html. only scope variables can directly bind to html using curly brackets. so inside foo function var one should assign to scope.one in order to display it in the html.
angular.module("app",[])
.controller("ctrl",function($scope){
var one = 1;
$scope.name = name;
$scope.foo = function(){
$scope.one = one;
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<input type="text" ng-model="name">
<p>{{name}}</p>
<p>{{one}}</p>
<button ng-click="foo()">1</button>
</div>
I wish I can handle this, but in the bad way...namely I need to use $cookieStore to check either the function called or not.
Every time to use push array then I need to use $cookieStore. But it seems not practical.
Here was my DOM:
<div ng-controller="MyCtrl">
<div>
<div ng-include="'temp2.html'">
Hello, {{name}}!
</div>
</div>
</div>
<script type="text/ng-template" id="temp2.html">
<div ng-controller="MyCtrl">Another View</div>
</script>
And my angularjs controller:
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.name = 'Superhero';
alert(1);
}
alert(1) function will be called 2 times every times the page was called.
How to avoid this problem without using watcher?
My fiddle for your convenience. Thanks!
The controller would called be twice for both the views, i would suggest you to move controller specific code to init function and use ng-init in one of your views.
var Controller = function($scope) {
$scope.init = function () {
};
};
Your View
<div ng-controller="Controller" ng-init="init()"/>
Yo don't need to specify the Controller name again in the include.... if its the same as the parent one(same as controller of main page).
just go with this
<div ng-controller="MyCtrl">
<div>
<div ng-include="'temp2.html'">
Hello, {{name}}!
</div>
</div>
</div>
<script type="text/ng-template" id="temp2.html">
<div>Another View {{name}}</div>
</script>
Js Fiddel
name will be accessible in the view you included.
Hope it will help you..
I have a Angular JS Application,
<div class="col-lg-12" ng-init="getTableData('{{URL::route('get_repair_category')}}')">
When Page loading the getTableData will execute, but I want to check a variable $rootScope.Dealer and switch the function name of initialization.
Eg : if $rootScope.Dealer value present I wanto execute the function named getDealerData
And If the value is not set need to execute the getTableData function.
How can I make this in anglar js template.
I just tried the ng-if, but its not working...
You can use simple Javascript syntax in ng-init directive like this:
<div class="col-lg-12" ng-init="Dealer ? getDealerData('{{URL::route('get_repair_category')}}') : getTableData('{{URL::route('get_repair_category')}}')">
Here is a plnkr for you (I've changed backend route generation to text):
https://plnkr.co/edit/CJOMT0g50BCWa3j02rcS?p=preview
Try this
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope, $rootScope) {
$rootScope.dealer = ["a", "b", "c"];
$scope.getTableData = function(x) {
return x;
}
$scope.getDelearData = function() {
return $rootScope.dealer;
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-init="data = getDelearData() || getTableData('table data')">
{{data}}
</div>
</div>
Consider two div areas as follows, in html file
<div class="divArea1" ng-controller="myController">
<input ng-click="updateName()" type="button" value="button"/>
</div>
<div class="divArea1" ng-controller="myController">
<p>{{name}}</p>
</div>
Following is the angular js example
productApp.controller("myController", [ '$scope', function($scope) {
$scope.name= "XYZ";
$scope.updateName= function() {
$scope.name = "ABC";
};
} ]);
problem is when I am trying to update the name, upon click on update button it is not visible in the second in the div area. Is there any mistake i am doing.
What you have is two different controllers (with two separate scopes) with the same name.
You need to put the controller in the parent controller to keep the name in the same scope as the button:
<div id="container" ng-controller="myController">
<div class="divArea1">
<input ng-click="updateName()" type="button" value="button"/>
</div>
<div class="divArea1">
<p>{{name}}</p>
</div>
</div>
Controllers are not singletons. Each time you have a new controller, you're having a new instance of this controller, with a new isolated scope.
If your need is to share data between controllers, you should use a factory (which is a singleton).
angular.module('app').factory('mySharedData', function(){
var service = {
object : objectToShare
};
var objectToShare = {};
return service;
});
And from your controller :
angular.module('app').controller('myController',
['$scope','mySharedData',
function($scope, mySharedData){
$scope.someObject = mySharedData.object;
$scope.updateName= function() {
$scope.someObject.name = "ABC";
};
}
]);
And from your view :
<div class="divArea1" ng-controller="myController">
<input ng-click="updateName()" type="button" value="button"/>
</div>
<div class="divArea1" ng-controller="myController">
<p>{{someObject.name}}</p>
</div>
Note : I've encapsulated the name property into an object because objects are passed by reference, and strings by value. This allows you to make it easier to share your values and to have it automatically updated into the service and other controllers, without having to access your property through accessors.
here is demo http://jsfiddle.net/wg7pb1yu/3/
inject $rootScope so that it will do from global scope
productApp.controller("myController", [ '$scope','$rootScope', function($scope, $rootScope) {
$rootScope.name= "XYZ";
$scope.updateName= function() {
$rootScope.name = "ABC";
};} ]);
Hope this will help you
HTML
<section ng-app="app">
<table ng-controller="VoicemailsCtrl">
<caption>{{test}}</caption>
</table>
</section>
JS
var app = angular.module('app', [])
.controller('VoicemailsCtrl', ['$scope', VoicemailsCtrl]);
function VoicemailsCtrl($scope, $http)
{
$scope.vms = [1,2,3];
$scope.test = 'this is a test';
}
Can be seen at:
http://jsfiddle.net/tx9nbo8g/6/
You missed adding
ng-app="app"
in the section.
Check the updated fiddle
Fiddle
Apart from this you need to add
angular 1.2.1
and
No wrap in head
in framework and extension.
.
Please find below working code :
Html:
<body ng-app="app">
<section>
<table ng-controller="VoicemailsCtrl">
<caption>{{test}}</caption>
</table>
</section>
</body>
Js:
var app = angular.module('app', []);
app.controller('VoicemailsCtrl', ['$scope','$http',VoicemailsCtrl]); //You forgot to add $http
function VoicemailsCtrl($scope, $http) {
$scope.vms = [1,2,3];
$scope.test = 'this is a test';
}
http://plnkr.co/edit/qCsG4WzFc0Irt2RobLoC?p=preview
Add ng-app="app" on section element & also you need to change the script loading option inside your fiddle from OnLoad to No Wrap in <head/>
Markup
<section ng-app="app">
<table ng-controller="VoicemailsCtrl">
<caption>{{test}}</caption>
</table>
</section>
Working Fiddle
Your HTML should have to be changed. You need to tell angular where app is starting. Default ng-app is also a valid app declaration.
<section ng-app="MyApp">
<table ng-controller="VoicemailsCtrl">
<caption>{{test}}</caption>
</table>
</section>
In controller
angular.module('MyApp', [])
.controller('VoicemailsCtrl', ['$scope', function ($scope){
$scope.vms = [1,2,3];
$scope.test = 'this is a test';
}]);
fiddle
You should not use global declaration of controller. Its been deprecated in angular 1.3+ versions. You should use controller directive to declare a controller.