ng-controller App data not binding properly - angularjs

I have to finish this assignment. I am trying to print out the contacts in contactsController and be able to add to this list. I can't figure out where I am going wrong. Can anyone help. I have an array contacts[] in contactController and I am trying to print out the list in html using ng-repeat="contact in contactsController.contacts" and binding to contact.name and contact.type.
<!doctype html>
<html ng-app>
<head>
<style>
</style>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
</head>
<body>
<div ng-controller="contactsController">
<label>Name</label>
<input ng-model="contactsController.contacts.name" type="text" placeholder="Name">
<label>email</label>
<input ng-model="contactsController.email" type="text" placeholder="Email">
<button ng-click="addContact()">Add contact</button>
</div>
<div>{{contactsController.name}}</div>
<div>
<ul>
<li ng-repeat="contact in contactsController.contacts">
<div>{{contact.name}}</div>
<div>{{contact.email}}</div>
<div><button ng-click="deleteContact($index)">delete</button></div>
</li>
</ul>
</div>
<script>
// Your code goes here.
// $( document ).ready(function() {
// alert('jQuery asdfas!');
// Your code here.
// });
function contactsController($scope){
$scope.contacts=[{name:'asdf',email:'asdf'},
{name:'yweuir',email:'xcvzx'}
];
contactsController.prototype.addContact =function($scope){
console.log(this.name);
console.log(this.email);
this.contacts.push({name:this.name,email:this.email});
}
}
</script>
</body>
</html>

Your repeat is wrong. It should be:
ng-repeat="contact in contacts"
When you are doing a repeat, the reference to the array assumes it's in $scope already. Your controller has nothing to do with it. So if you had:
$scope.contractsController = {
contacts: {...}
}
Your code would work. But your controller is fine, just remove the reference from the repeat.

I'll create a plunker so you can check the detail changes in the revisions.
http://plnkr.co/edit/NrbLiIFw4EbxEfYJm41J?p=preview
The HTML had a wrong indentation, and the ng-repeat was outside of the ng-controller block.
Also, was missing the injection of the controller into the module of the application, i rewrote the application using the general application declaration with ngApp directive.
If you want an example more detailed you can check the TodoMVC angular application
https://github.com/tastejs/todomvc/tree/gh-pages/architecture-examples/angularjs-perf
Other examples:
http://todomvc.com/architecture-examples/angularjs/#/
All the best

Hey I'll create a plnkr link.
Here is link Check this:
http://plnkr.co/edit/mzcAC5yU9P6Mb3nfGByP?p=preview
Here is Code:
<!DOCTYPE html>
<html ng-app = "app">
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js">
</script>
<script>
angular.module("app",[]).controller('contactsController',['$scope',
function($scope) {
$scope.contacts=[{name:'Abhi',email:'Abhi#test.com'},
{name:'Sharma',email:'sharma#test.com'}
];
$scope.addContact =function(){
this.contacts.push({name:this.name,email:this.email});
$scope.name = '';
$scope.email = '';
}
$scope.deleteContact = function (index) {
$scope.contacts.splice(index, 1);
}
}
]);
</script>
</head>
<body ng-controller="contactsController">
<label>Name</label>
<input ng-model="name" type="text" placeholder="Name">
<label>email</label>
<input ng-model="email" type="text" placeholder="Email">
<button ng-click="addContact()">Add contact</button>
<div>
<ul>
<li ng-repeat="contact in contacts">
<div>{{contact.name}}</div>
<div>{{contact.email}}</div>
<div><button ng-click="deleteContact($index)">delete</button></div>
</li>
</ul>
</div>
</body>
</html>
May be it help you..
Thanks

You don't prefix your values with the controller name. The ng-controller section basically sets the scope for the child elements to an instance of the controller. So what's happening in your code currently is that it's checking the contactsController for an attribute of contactsController.

Related

angular uib-popover-template input two-way binding

I am working on uib-popover recently, I found a problem that I am confused with.
I want to popover a template, in this template I have an input, at first the input have initial value.
I want to update the content real-time based on the input. When I just bind a variable, it does not work, while if I bind an object, it works. I can't figure this problem out.
index.html
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-animate.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-sanitize.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.4.0.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="PopoverDemoCtrl">
<hr/>
<hr/>
<hr/>
<button uib-popover-template="'myPopoverTemplate.html'" popover-placement="bottom-left" type="button" class="btn btn-default">Popover With Template</button>
{{dynamicPopover.title}}
<script type="text/ng-template" id="myPopoverTemplate.html">
<div class="form-group">
<input type="text" ng-model="dynamicPopover.title" class="form-control">
</div>
</script>
<button uib-popover-template="'inputContent.html'" popover-placement="bottom-left" type="button" class="btn btn-default">Popover With Template</button>
{{inputContent}}
<script type="text/ng-template" id="inputContent.html">
<div class="form-group">
<input type="text" ng-model="inputContent" class="form-control">
</div>
</script>
</div>
</body>
</html>
example.js
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('PopoverDemoCtrl', function($scope, $sce) {
$scope.dynamicPopover = {
title: 'Title'
};
$scope.inputContent = "hello";
});
Here is the plunker example https://plnkr.co/edit/IPXb5tddEPQPPAUrjdYx?p=preview, you could have a try.
You made an interesting point in your second plunk. I didn't catch this the first time but I think it may be because you are doing your popover input in a script tag. I would suggest using a custom directive if you could versus just doing it in an inline script. That way it is kept up to date with angular's digest cycle.
Example Directive:
customPopoverApp.directive('customPopover',['$compile','$templateCache',function($compile,$templateCache){
return {
restrict:'A',
transclude:true,
template:"<span>Click on me to show the popover</span>",
link:function(scope,element,attr){
var contentHtml = $templateCache.get("customPopover.html");
contentHtml=$compile(contentHtml)(scope);
$(element).popover({
trigger:'click',
html:true,
content:contentHtml,
placement:attr.popoverPlace
});
}
};
}]);
And to use it:
<button custom-popover="" popover-place="bottom">click on me to show the popover</button>
{{message}}
<script type="text/ng-template" id="customPopover.html">
<div class="form-group">
<input type="text" ng-model="message" class="form-control">
</div>
</script>
Here is a working plunk. I hope this is what you're looking for

Model is not reflected when I use same controller with two divs

I have given same controller in two divs but model that gets updated in one div does not reflect in another.
<body ng-app="myApp">
<div ng-controller="filterCtrl">
<p ng-bind="test" />
</div>
<div ng-controller="filterCtrl">
<p><input type="text" ng-model="test" ng-change="handleChange()"></p>
</div>
</body>
When I am entering into the text box it's not updating the above div's "ng--bind". Though, if I put that "ng-bind" in the div having text box, it's working fine. Kindly help me on this.
it should be like that
<html ng-app="myApp">
<body ng-controller="filterCtrl">
<div>
<p>{{test.text}}</p>
</div>
<div>
<p><input type="text" ng-model="test.text" ng-change="handleChange()"></p>
</div>
</body>
</html>
here example on plunker
Nothing bad to reuse controller in your code: fiddle
As you can see they both works, but independently.
It's because each other instantiate its own scope. If you want them to talk, you can to make it via some services or to create some common scope for both of them, or merge them into one controller instance.
You can use parent scope as common part for both.
<div ng-controller="MainCtrlr as c">
<input ng-model="$parent.name" />
Hello, {{$parent.name}}!!!
</div>
<div ng-controller="MainCtrlr as c">
<input ng-model="$parent.name" />
Hello, {{$parent.name}}!!!
</div>
Fiddle
Talk via services will be much better than this:
Code:
angular.module('app', [])
.controller('MainCtrlr', ['MainData', function(MD){
this.MD = MD;
MD.name = 'World';
}]).service('MainData', [function(){}])
Template:
<div ng-controller="MainCtrlr as c">
<input ng-model="c.MD.name" />
Hello, {{c.MD.name}}!!!
</div>
<div ng-controller="MainCtrlr as c">
<input ng-model="c.MD.name" />
Hello, {{c.MD.name}}!!!
</div>
Fiddle
Problem:
If we try to associate same controller with two divs then angular creates two different scopes for those two divs.
And if we try to update scope in one instance then it will not be reflected to other instance.
There are two ways to get rid of from this situation:
You can create one mainCntrl that have filterCtrl as its child controller.
And assumed mainCntrl has mainView scope property. We created a mainView object on the mainCntrl,
and since filterCtrl and its scope prototypally inherit from mainCntrl so we can always reach that mainView in any instance of filterCtrl.
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<html>
<head>
<script>
angular.module('myApp', [])
.controller('mainCntrl', function($scope) {
$scope.mainView = {};
$scope.mainView.x = 'Something';
})
.controller('filterCtrl', function($scope) {
});
</script>
</head>
<body ng-app="myApp">
<div ng-controller="mainCntrl">
<div ng-controller="filterCtrl">
<p ng-bind="mainView.x" />
</div>
<div ng-controller="filterCtrl">
<p><input type="text" ng-model="mainView.x" ng-change="handleChange()"></p>
</div>
</div>
</body>
</html>
We can utilized $parent which can be accessed through $scope.$parent. This place will be the common place for all the instances of filterCtrl.
So whatever we put over $scope.$parent, will be accissible to all the instances.
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<html>
<head>
<script>
angular.module('myApp', [])
.controller('filterCtrl', function($scope) {
$scope.$parent.test = 'Something';
});
</script>
</head>
<body ng-app="myApp">
<div ng-controller="filterCtrl">
<p ng-bind="$parent.test" />
</div>
<div ng-controller="filterCtrl">
<p><input type="text" ng-model="$parent.test" ng-change="handleChange()"></p>
</div>
</body>
</html>

Angularjs ng-fx animation applied to the wrong element

I have created a simple app with simple animations where I can add and remove items to an array (used ng-fx for animations), but I have a problem.
When I try to add new elements, I get ng-repeat duplicate error. I fixed it by adding track by $index, but this time a new error occurs. If I try to remove an element from the list, wrong one is being animated.
Here's my plnkr
http://plnkr.co/edit/hKk9VGHIE1GT2i3P8TtT?p=preview
Here's my code.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.5.0" data-semver="1.5.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
<script src="angular-animate.min.js"></script>
<script src="ng-fx.js"></script>
</head>
<body ng-app="app">
<div ng-controller="FirstController">
<div ng-repeat="name in names track by $index" class="fx-fade-normal">
{{name}}
<input type="submit" value="Remove" ng-click="remove($index)">
</div>
<input type="text" ng-model="name" />
<input type="submit" value="Add" ng-click="add()">
</div>
<script>
angular.module('app', ['ngAnimate', 'ng-fx']);
angular.module('app').controller('FirstController', ["$scope", function($scope) {
$scope.names = ["first", "second", "third", "fourth"];
$scope.add = function() {
$scope.names.push($scope.name);
};
$scope.remove = function($index) {
$scope.names.splice($index, 1);
};
}]);
</script>
</body>
</html>
It's simple change ng-repeat="name in names track by $index" to ng-repeat="name in names track by $id(name)"

Simple single page application is not running

I am new to angular.js and I was trying my hands on it. Can anyone please tell me why this program is not running?
HTML code:
<!DOCTYPE html>
<html ng-app="demoApp">
<head>
<link data-require="bootstrap#*" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
<script data-require="bootstrap#*" data-semver="3.3.6" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.js"></script>
<script data-require="jquery#>=1.9.1 <3" data-semver="2.1.4" src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script data-require="angular.js#*" data-semver="2.0.0-alpha.45" src="https://code.angularjs.org/2.0.0-alpha.45/angular2.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<h1>Hello Plunker!</h1>
<div ng-controller="SimpleController">
Name:
<br/>
<input type="text" ng-model="name" />
<br/>
<ul>
<li ng-repeat="cust in customers | filter:name"></li>
</ul>
</div>
</body>
</html>
JS code:
// Code goes here
var demoApp = angular.module ('demoApp', []);
function SimpleController($scope){
$scope.customers=[
{name:'xx xx' city:'xx'},
{name:'yy yy' city:'yy'},
{name:'zz zz' city:'zz'}
];
}
demoApp.controller('SimpleController', SimpleController);
You have several errors in you sample:
The main problem is that you're using the Angular 1.x.x syntax while you have the Angular 2.x.x script included in your app. Change the script for the previous release of the framework.
<script data-require="angular.js#1.4.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js" data-semver="1.4.8"></script>
The customers object is not a valid JSON as separation commas between properties are missing. It should look like this:
$scope.customers=[
{name:'parikshit mishra', city:'jaipur'},
{name:'nirmal vatsyayan', city:'delhi'},
{name:'ningning numeyi', city:'noida'}
];
You don't show anything using ng-repeat directive, you simply create several empty <li> tags, hence there's no content inside them. You need to display the variable that you iterate. If you want to show only the name property of the object, use simple dot syntax.
<li ng-repeat="cust in customers">{{cust.name}}</li>
Your input filed has ng-model attached, but you don't use the variable that is bound to it. You can refer to the variable with {{name}}.
Name: {{name}}<br/>
<input type="text" ng-model="name"/>
To see the big picture, here's the fixed sample.
Please refer to below code
HTML
<h1>Hello Plunker!</h1>
<div ng-controller="SimpleController">
Name: <br/>
<input type="text" ng-model="name"/>
<br/>
<ul>
<li ng-repeat="cust in customers| filter:name">{{cust}}</li>
</ul>
</div>
Angular
var demoApp = angular.module ('demoApp', []);
function SimpleController($scope){
$scope.customers=[
{name:'parikshit mishra', city:'jaipur'},
{name:'nirmal vatsyayan', city:'delhi'},
{name:'ningning numeyi', city:'noida'}
];
}
demoApp.controller('SimpleController', SimpleController);
Please refer
Problem
$scope.customers is not a valid object(missing commas between properties).
You have not displayed anything inside ng-repeat. Please use {{cust}}. Please refer ng-repeat.
The scripts inside your plunker are wrong.
Here is the fiddle demo.
js
$scope.customers=[
{name:'parikshit mishra', city:'jaipur'},
{name:'nirmal vatsyayan', city:'delhi'},
{name:'ningning numeyi', city:'noida'}
];
html
<li ng-repeat="cust in customers | filter:name">
{{ cust.name }}
</li>
hope this will help you

Pro AngularJS Chapter 12 | Working With Forms | Using Checkboxes

I am working through Pro AngularJS by Adam Freeman and have not been able to get the Using Checkboxes example to work.
The example tries to show that you can set attributes ng-true-value="Hurrah!" and ng-false-value="Boo!" and are displayed through ng-model="inputValue".
This is not working.
I am only able to get this sample to work by setting integer values inside ng-true-value and ng-false-value.
<!DOCTYPE html>
<html ng-app="exampleApp">
<head>
<title>Forms</title>
<script src="angular.js"></script>
<link href="bootstrap.css" rel="stylesheet" />
<link href="bootstrap-theme.css" rel="stylesheet" />
<script>
angular.module("exampleApp", [])
.controller("defaultCtrl", function ($scope) {});
</script>
</head>
<body>
<div id="todoPanel" class="panel" ng-controller="defaultCtrl">
<form name="myForm" novalidate>
<div class="well">
<div class="checkbox">
<label>
<input name="sample" type="checkbox" ng-model="inputValue"
ng-true-value="Hurrah!" ng-false-value="Boo!">
This is a checkbox
</label>
</div>
</div>
<div class="well">
<p>Model Value: {{inputValue}}</p>
</div>
</form>
</div>
</body>
</html>
According to the documentation for input[checkbox], ng-true-value and ng-false-value accept expressions. Since you are trying to pass a string literal as the value, you need to enclose them in an addional pair of quotes.
Try ng-true-value="'Hurrah!'" ng-false-value="'Boo!'"

Resources