two way binding not working with ng-repeat - javascript

I have a simple ng-repeat list, in which i am assigning current list item value to another property on the controller as follows:
<li ng-repeat="num in list">
<input type="text" ng-init="value = num" ng-model="value" />
<button type="button" class="btn btn-primary" ng-click="save()">Save</button>
</li>
But when i click the Save button i get default value set for $scope.value. I expect the value for the particular input text to be displayed.
Here is the controller:
angular.module('myApp', [])
.controller('MyController', function($scope){
$scope.value = false;
$scope.list = [0, 1, 2, 3, 4];
$scope.save = function() {
alert($scope.value);
}
});
How can i access the updated value of a input item in my controller on save function call.
Here is the plunker for the same: plnkr
Update: I am expecting the value to be fetched to controller without passing it as a parameter.

Wow I can't believe most people have missed this. If you are using Angular 1.2 then you should definitely check out track by keyword in your ngRepeat directive.
<li ng-repeat="num in list track by $index">
<input type="text" ng-model="list[$index]" />
<button type="button" class="btn btn-primary" ng-click="save()">Save</button>
</li>
Bottom line is stay away from primitive types when binding since it will give you sync issues.
Fellas please put more time and effort into researching your solutions instead of just posting for points.
Hope this helps!

ngRepeat create a scope, so, object is passed by reference and number by value.
Your code is problematic, if you successfully update the value, it will update all the numbers in ng-repeat. You can do this:
html
{{value.val}} <!-- for check the value -->
<li ng-repeat="num in list">
<input type="text" ng-model="num" />
<button type="button" class="btn btn-primary" ng-click="value.val=num">Save</button>
</li>
javascript
angular.module('myApp', [])
.controller('MyController', function($scope){
$scope.value = {val:false};
$scope.list = [0,1,2,3,4];
});
http://jsfiddle.net/oq6zdeLd/
I'm sorry about my english...

here it is how you can do that
<li ng-repeat="num in list">
<input type="text" ng-init="value = num" ng-model="value" />
<button type="button" class="btn btn-primary" ng-click="save(value)">Save</button>
</li>
angular.module('myApp', [])
.controller('MyController', function($scope){
$scope.value = false;
$scope.list = [0, 1, 2, 3, 4];
$scope.save = function(argument) {
$scope.value = argument;
alert($scope.value);
}
});

Lets not abuse the expression "2 way binding" ;)
Your controller has one scope and there is just one $scope.value in that scope. You cannot force is to have multiple values simultaneously.
ng-repeat creates new scope for each li. And even if you try to use $parent.value, your controller's $scope.value will only have the last assigned value in ng-init
You best bet in this case to pass the value as an argument. Hope this helped to explain the issue a little more. Correct me if I am wrong.

Related

Need to get value of the radio button and pass it to the backend using HTML and angularJS,and the data displayed in the frontend is a list

//This is my HTML code wherein am returning a list from backend.
<ul>
<li ng-repeat=" opt in bcfList1 track by $index" > <input type="radio" name="buildid" id="buildid" ng-model = $parent.selected ng-value="bcfList1" required>
{{ opt }}
</li>
</ul>
//This is my controller.js program
$scope.getDetails =function(data){
var id=data.id;
$('#addNode3').modal('show');
UpgradeService.getDataById(id).then(function(data){
if(data!=null){
$scope.List1=data.BUILDNUMBER;
}
});
}
I need to get the string value that'll be listed in front of the radio button. So once I click on radio button it should send that value to the controller.js
By using ng-model I need a solution.
Help me out!!
You need to add ng-change to your input fields with a call to that function. Here is a quick demo:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.b = [1, 2, 3, 4, 5, 6, 7, 8, 9];
$scope.getDetails = function(index) {
console.log("sending data", index,$scope.selected);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="a in b track by $index">
<input type="radio" ng-model="$parent.selected" ng-value="a" ng-change="getDetails($index)" /> {{a}}
</div>
</div>
If I understand correctly, you need to gather which input type radio was clicked in controller and send this information to backend.
ng-model directive is very good approach here and you can use it just like so:
html
<label>
One
<input type="radio" value="one" ng-model="radio">
</label>
<label>
Two
<input type="radio" value="two" ng-model="radio">
</label>
<br><br>{{ radio }}<br>
JS
app.controller('MainCtrl', function($scope) {
$scope.radio = '';
$scope.consoleLogRadio = function() {
console.log($scope.radio);
}
});
Take a look at plunker example

AngularJS data binding not working - within the controller Scope variables are not showing the entered value

I have a strange situation in which $scope variables binding do not appear to be work as expected.
Here is the HTML:
<div class="input-group" style="width:100px">
<input type="number"
class="form-control"
id="Sampling_Request_for_Current_Sampling_INPUT"
ng-model="aabbcc"
style="width:125px;text-align:center">
<span class="input-group-btn">
<button class="btn btn-default" ng-disabled="Cannot_Allocate_Yet" ng-click="Get_Sampling_Request_Details()" type="button">{{All_Labels.Common.Display}}</button>
</span>
</div>
and here is the scope function invoked upon clicking on the button:
$scope.Get_Sampling_Request_Details = function () {
console.log("$scope.aabbcc: " + $scope.aabbcc) ;
}
The variable $scope.aabbcc is initialized to 0 upon controller's loading.
Regardless what I type into the input element, I always get 0 in the console.
This scenario generally happens, If you have wrapped your HTML inside ng-if, ng-switch ng-repeat.. or some other directive that creates new child scope.
See this fiddle.
So it's a best practice to wrap your scope in some model to leverage protypical inheritance and correctly bind data to $scope.
Like : $scope.data.aabbcc = 0 and use it like ng-model ='data.aabbcc'.
See this for few minutes and Read this for complete understanding.
check this working example
<div ng-controller="MyCtrl">
Hello, {{name}}!
<input type="number" ng-model="name"/>
<button class="btn btn-default" ng-disabled="Cannot_Allocate_Yet" ng-
click="Get_Sampling_Request_Details()" type="button">test</button>
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.name = 0;
$scope.Get_Sampling_Request_Details = function () {
console.log("$scope.aabbcc: " + $scope.name) ;
}
}
AngularJS controllers control the data. The scope is the binding part between the HTML (view) and the JavaScript (controller). You must define the ng-model inside a ng-controller within which its scope lies. Try this out.
<div ng-controller="myCtrl">
<div class="input-group" style="width:100px">
<input type="number"
class="form-control"
id="Sampling_Request_for_Current_Sampling_INPUT"
ng-model="aabbcc"
style="width:125px;text-align:center">
<span class="input-group-btn">
<button class="btn btn-default" ng-disabled="Cannot_Allocate_Yet" ng-click="Get_Sampling_Request_Details()" type="button">{{All_Labels.Common.Display}}</button>
</span>
</div>
</div>
<script>
var app = angular.module('Myapp', []);
app.controller('myCtrl', function($scope) {
$scope.Get_Sampling_Request_Details = function () {
console.log("$scope.aabbcc: " + $scope.aabbcc) ;
}
});
</script>
Declare an empty object in your controller section .
eg: $scope.obj = {};
And use like ng-model="obj.key_name" in your html. It will work.

To access selected radio button value in angular controller

I am unable to get the value of a selected radio button in angular controller. The reportTypeId I use in angular controller does not fetch the value of the radio button. Can someone guide me where exactly I am wrong ?
HTML
<div class="col-md-3">
<input type="radio" ng-model="reportTypeRadio" value="reportType.reportTypeId">
<a href="#reportTypeEntityList/{{reportType.reportTypeId}}">
{{reportType.reportTypeLabel}}
</a>
</div>
Controller
mdmApp.controller('Controller', function($scope, $http, $location, $routeParams) {
$scope.reportTypeRadio = reportTypeId;
$scope.viewReportTypeEntityList = function() {
$location.path('/reportTypeEntityList/' +reportTypeId);
}
});
You need to use model value from ngModel directive:
$scope.viewReportTypeEntityList = function() {
$location.path('/reportTypeEntityList/' + $scope.reportTypeRadio);
};
It worked. I just made the below changes to my html. used ng-value instead of value, and $parent in ng-model to use the parent scope of the ng-repeat directive.
<div class="col-md-3">
<input type="radio" ng-model="$parent.reportTypeRadio" ng-value="reportType.reportTypeId">
<a href="#reportTypeEntityList/{{reportType.reportTypeId}}">
{{reportType.reportTypeLabel}}
</a>

Angular JS how to pass value from rootscope into ng-model?

I have object into rootscope and i would like to display some values in form inputs.
I tried following:
<input type="number" ng-model="$root.order.id" class="form-control" id="orderNumber" />
But this is not working.
How i should pass value into ng-model?
Thanks for any help.
No need of attach de $root to the variable, the flow of scope in angular is first search in the local scope for the variable, if not found search the property in $scope.parent, and the rootScope if the high level of parent if not match with any else, then search there.
http://plnkr.co/edit/3ENyPRwrFq5ssR2uLtQy
In this plnkr look the usage of the root scope
Controller:
app.controller('MainCtrl', ["$scope", "$rootScope", function($scope, $rootScope) {
$rootScope.varRoot = {
element: "Jesús"
};
}]
);
HTML:
<body ng-controller="MainCtrl">
<p>Hello {{varRoot.element}}!</p>
<input type="text" ng-model="varRoot.element">
</body>
Just use the name, ex:
$rootScope.order.id = 3;
<input type="number" ng-model="order.id" class="form-control" id="orderNumber" />

How to get an element's attribute with AngularJS

I have the following code:
<div class="col-md-10" data-ng-controller="type-controller">
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-success" ng-model="typeId" data-btn-radio="'1'">
Option 1
</label>
<label class="btn btn-success" ng-model="typeId" data-btn-radio="'2'">
Option 2
</label>
</div>
<input data-ng-model="typeId" name="typeId" type="hidden" data-start="2" />
</div>
My type-controller is empty so I'm omitting it - but I want to get the value of the attribute data-start from the last input inside the type-controller.
I'm not using jQuery.
IF the attribute data-start is significant because it is being used by some other 3rd party library, then you might consider simply using ng-init when you create this on the server:
<input data-ng-model="typeId" name="typeId" type="hidden" data-start="2"
ng-init='start = 2' />
This will essentially run any code you need, and doesn't involve you having to parse out data attributes from the DOM.
You could write a pretty trivial directive to pull in the value and publish using an expression. This will essentially accomplish the same thing, but is more difficult in my opinion:
angular.module('data-pluck', [])
.controller('fooController', function() {
this.name = 'Foo Controller';
})
.directive('pluckData', ['$parse',
function($parse) {
return {
restrict: 'A',
link: function(scope, elem, attrs) {
var expression = function() {};
expression.assign = function() {};
scope.$watch(attrs.placeData, function() {
expression = $parse(attrs.placeData);
});
scope.$watch(attrs.pluckData, function() {
expression.assign(scope, attrs[attrs.pluckData]);
});
}
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='data-pluck' ng-controller='fooController as ctrl'>
<h1>{{ctrl.name}}</h1>
<div data-my-val="I'm value one" pluck-data='myVal' place-data='ctrl.valueOne'>
<p>I'm a regular old <code><p></code> tag</p>
<input type='hidden' data-my-val="I'm the second value" pluck-data='myVal' place-data='ctrl.valueTwo' />
</div>
<h3>These Values Populated Dynamically</h3>
<ul>
<li>ctrl.valueOne = {{ctrl.valueOne}}</li>
<li>ctrl.valueTwo = {{ctrl.valueTwo}}</li>
</ul>
</div>
Angular comes with jqLite built in, which still has the attr() function. But it's not the Angular "way" to be manually fiddling around in the DOM from a controller. Your scope should be the interface between them.
I'm curious as to why you have a value in an attribute in your UI that isn't defined first in your model / scope? How does this value get changed? Is there a reason why you can't set it in the controller:
$scope.start = 2;
and then:
<input data-ng-model="typeId" name="typeId" type="hidden" data-start="{{start}}" />
Can you explain a little about what data-start is meant to do?

Categories