parseInt not converting multiple string to int - angularjs

it was a very simple but don't no why i can't solve it.
I am trying to convert string to integer from json, it converts 1st object but from second object it doesn't:
HTML:
<body ng-controller="myApp">
<ul ng-repeat="vals in json_arr" ng-init="parseId(vals)">
<li>
<input type="number" ng-model="vals.id" />
</li>
<li>
<input type="number" ng-model="vals.id1" />
</li>
<li>
<input type="number" ng-model="vals.id2" />
</li>
</ul>
</body>
Controller:
app.controller('myApp', function($scope) {
$scope.json_arr = [{
'id': '1',
'id1': '2',
'id2': '3'
}];
$scope.parseId = function(val) {
val.id = parseInt(val.id);
}
});
DEMO PLUNKER

Aahhhhh that's my mistake, In parseId function i only parse val.id.
The correct 1 is:
$scope.parseId = function(val) {
val.id = parseInt(val.id);
val.id1 = parseInt(val.id1);
val.id2 = parseInt(val.id2);
}

change your code with this one
$scope.parseId = function(val) {
val.id = parseInt(val.id);
val.id1 = parseInt(val.id1);
val.id2 = parseInt(val.id2);
}
or you can change your json_arr variable than you don't need to change string to int
$scope.json_arr = [{
'id': 1,
'id1': 2,
'id2': 3
}];

Directives are executed in order from highest priority to lowest priority when defined on the same element. ng-repeat has a directive priority level of 1000, but ng-init has a directive priority of 450. ng-repeat also has a terminal property - meaning it is the last directive to execute, and no other directives can execute after it. There-in lies the problem. The ng-repeat executes first, and because it is terminal, it will not allow ng-init to execute after.
To solve this, move the ng-init to the first li below:
<body ng-controller="myApp">
<ul ng-repeat="vals in json_arr">
<li ng-init="parseId(vals)">
<input type="number" ng-model="vals.id" />
</li>
<li>
<input type="number" ng-model="vals.id1" />
</li>
<li>
<input type="number" ng-model="vals.id2" />
</li>
</ul>
</body>
This works because ng-model has a priority of 0, so it will execute after ng-init.
[EDIT]
I realized there is a logic error in the code you posted. The other two answers have already addressed it, but I'll post it again here for completeness:
$scope.parseId = function(val) {
val.id = parseInt(val.id);
val.id1 = parseInt(val.id1);
val.id2 = parseInt(val.id2);
}

Related

Angular - inside an ng-repeat, checkbox state to affect only one element

If I have for example a simple todo list:
HTML
<ul ng-repeat="todos in keyVar.list">
<li ng-class="{ 'completed' : keyVar.toggle }">
{{ todos }}
<input ng-if="!keyVar.toggle" type = "checkbox" ng-click="keyVar.toggle=true" >
<input ng-if="keyVar.toggle" type = "checkbox" checked= "true" ng-click="keyVar.toggle=false" ></input>
</li>
</ul>
JS
angular.module("todoApp", [])
.controller("mainCtrl", function(){
var keyVar = this;
keyVar.title ="Angular Todos";
keyVar.list=[];
keyVar.toggle = false;
keyVar.todosArr = function(){
keyVar.list.push(keyVar.todo)
keyVar.todo = "";
}
});
When I run this, I can add a todo, and check and uncheck the checkbox which toggles a class of completed, but it gives the class to every todo and if I check one checkbox, all of them go checked. I think I have to use something like keyVar.list[$index]? But I'm not sure where to use it or how.
Try like this. I define for each todo a status. and bind that to checkbox. when user click on checkbox change it.
angular.module("todoApp", [])
.controller("mainCtrl", function(){
var keyVar = this;
keyVar.title ="Angular Todos";
keyVar.list=[
{
"title":"Todo1",
"status":false
},
{
"title":"Todo2",
"status":false
}
];
keyVar.todosArr = function(){
keyVar.list.push({title:keyVar.todo,status:false})
keyVar.todo = "";
}
});
.completed{
text-decoration: line-through;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="todoApp" ng-controller="mainCtrl as keyVar" class="container">
<input type="text" ng-model="keyVar.todo">
<button ng-click="keyVar.todosArr()">Add Todo</button>
<ul ng-repeat="todos in keyVar.list">
<li ng-class="{ 'completed' : todos.status }">
{{ todos.title }}
<input ng-model="todos.status" type = "checkbox" ng-click="keyVar.toggle=true" >
</li>
</ul>
</div>
Try use ng-checked instead of ng-click.
<input ng-if="!keyVar.toggle" ng-checked="keyVar.toggle=true">

How to get multiple radio button values in angularjs form?

I have questioner form, in their question have multple options. how to get user selected options?
Here is the code?
...
<ul>
<li ng-repeat="question in questionPaper.questions">
<div>{{question.description}}</div>
<ul>
<li ng-repeat="option in question.options">
<span>
<input type="radio" name="option_question_{{question.id}}" ng-model="option.id"/>
{{option.description}}
</span>
</li>
</ul>
</li>
</ul>
...
How to get option values as
{question_paper_id: 1, answers: [{question_id: 1, options_id: 23}, {question_id: 2, options_id: 21}, {..}] }
Here is my code in plnkr http://plnkr.co/edit/OTDsUUCiDGYfxJ2AMzFR
Basically, you can dynamically add a property when the radio button is selected:
<input type="radio" ng-model="question.selected_id" ng-value="option.id"/>
$scope.selected_ids = [];
$scope.submitAnswers = function() {
angular.forEach($scope.questionPaper.questions, function(question) {
$scope.selected_ids.push(question.selected_id);
});
}
Take a look at the demo: http://plnkr.co/edit/QG8XP0jfjyJPY1xaXx6d?p=preview
everything else seems to fine. just replace your script tag for including angular with this
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>

convert json string object to integer in ng-view

i am trying to convert json object to integer in ng-view:
json string:
$scope.json_arr = [{
'id': '1',
'name': 'abc'
},
{
'id': '2',
'name': 'xyz'
}];
in view:
<ul ng-repeat="vals in json_arr">
<li><input type="number" ng-model="vals.id" /></li>
<li><input type="text" ng-model="vals.name" /></li>
</ul>
when i see the ouput, the number field is coming blank as the value of the id object is string.
How do i convert string 'id':'1' to integer??
Demo Plunker
Use ng-init, this will run whenever a new element in the array appears for ng-repeat, if you use it like this:
<ul ng-repeat="vals in json_arr" ng-init="parseId(vals)">
<li><input type="number" ng-model="vals.id" /></li>
<li><input type="text" ng-model="vals.name" /></li>
</ul>
Then all that's left is to write the parseId function referenced
$scope.parseId = function(val){
val.id = parseInt(val.id);
}
Plunkr
try it
Html side
<ul ng-repeat="vals in json_arr">
<li> <input type="number" value="{{convertToInt(vals.id)}}"/></li>
<li><input type="text" ng-model="vals.name" /> </li>
</ul>
Js Side
$scope.convertToInt= function (value) {
return parseInt(value);
};
It's working for me.
Working Source code here
if you are using angular form to store one or more variable values and pass a request for api post or put method,
example:
component.ts file
`loginForm: FormGroup;
mockService: ServiceName;
this.loginForm = this.formBuilder.group({
Id: [''],
empID: [''],
roomID: ['']
});
this.loginForm.get('Id').setValue(parseInt(this.Id));
this.loginForm.get('empID').setValue(parseInt(this.empID));
this.loginForm.get('roomID').setValue(parseInt(this.roomID));
let request = JSON.stringify(this.loginForm.value);
this.mockloginService.loginValuesCheckmethod(request).subscribe((response) => {
if (response.isSuccess && response.responseCode === '200') {}
This will pass payload value as int

Scope issue with ui-bootstrap tabs

I'm having a problem understanding scope. ui-bootstrap creates a new scope when you use tabset, I get that. I thought parent methods were available to child scopes? Here is a jsbin showing my problem.
JSBin
I'm sure there is something simple I'm missing, but I can't see it.
Code inline in case JSBin acts up:
angular.module('app', ['ui.bootstrap'])
.controller('MainController', function($scope) {
$scope.filters = [];
$scope.search = '';
$scope.providerVersions = [
{ name:'SomeOS', type:'pv' },
{ name:'OtherOS', type:'pv' }
];
$scope.scripts = [
{ name:'Something', pv:'SomeOS', type:'script' },
{ name:'Somebody', pv:'SomeOS', type:'script' },
{ name:'Other thing', pv:'OtherOS', type:'script' },
{ name:'Other body', pv:'OtherOS', type:'script' }
];
$scope.addFilter = function(f) {
$scope.filters.push({ name:f.name, type:f.type });
};
$scope.remFilter = function(i) {
$scope.filters.splice(i,1);
};
$scope.filterByName = function(n) {
var name = n.name.toLowerCase();
var search = $scope.search.toLowerCase();
return name.indexOf(search) > -1;
};
$scope.filterByFilters = function(f) {
if ($scope.filters.length===0) { return true; }
var byName = _.where($scope.filters, { type:'script' });
if (byName.length > 0) {
return _.contains(_.pluck(byName, 'name'), f.name);
}
return _.contains(_.pluck($scope.filters, 'name'), f.pv);
};
});
HTML
<body ng-app="app">
<div ng-controller="MainController">
<h3>This works</h3>
<p>Filters on both name and role as expected.</p>
<div ng-repeat="s in scripts|filter:filterByFilters">
{{ s.name }}
</div>
<form name="searchForm">
<input type="text" class="form-control" placeholder="Filter by name or role" ng-model="search">
</form>
<span ng-repeat="f in filters"><a ng-click="remFilter($index)">{{ f.name }}</a><span ng-if="!$last">, </span></span>
<ul ng-show="search.length>0" class="dropdown-menu" style="display:block; position:static;">
<li class="dropdown-header">Name</li>
<li ng-repeat="s in scripts|filter:filterByName"><a ng-click="addFilter(s)">{{ s.name }}</a></li>
<li class="divider"></li>
<li class="dropdown-header">Role</li>
<li ng-repeat="p in providerVersions|filter:search"><a ng-click="addFilter(p)">{{ p.name }}</a></li>
</ul>
<h3>This does not work</h3>
<p>Only filters on role. It does not call $scope.filterByName.</p>
<tabset>
<tab heading="Scripts">
<div ng-repeat="s in scripts|filter:filterByFilters">
{{ s.name }}
</div>
<form name="searchForm">
<input type="text" class="form-control" placeholder="Filter by name or role" ng-model="search">
</form>
<span ng-repeat="f in filters"><a ng-click="remFilter($index)">{{ f.name }}</a><span ng-if="!$last">, </span></span>
<ul ng-show="search.length>0" class="dropdown-menu" style="display:block; position:static;">
<li class="dropdown-header">Name</li>
<li ng-repeat="s in scripts|filter:filterByName"><a ng-click="addFilter(s)">{{ s.name }}</a></li>
<li class="divider"></li>
<li class="dropdown-header">Role</li>
<li ng-repeat="p in providerVersions|filter:search"><a ng-click="addFilter(p)">{{ p.name }}</a></li>
</ul>
</tab>
</tabset>
</div>
</body>
Scopes are interesting and confusing. All scopes, except $rootScape, have ancestors. I don't know for certain but I assume that the ui-bootstrap tabset creates its own isolate scope. That isolate scope does have a parent, but you've "isolated" it so it can't see any attributes of an ancestor scopes unless you've specifically included them within the directive. Should an isolate scope have a child scope that is not an isolate scope, it can see and manipulate its parents attributes but nothing farther back the ancestor chain. Events can pass freely up and down the chain and you should be very careful using them since, when dealing with isolate scopes, may cause side effects you aren't expecting.
If the above was just a bunch of blather, go to https://docs.angularjs.org/guide/directive and reread the info there - maybe that will make it more clear.
Here's probably one of the best dissertation on scope you'll fnd in a quick, concise and clear explanation - What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
I was able to work around this. Honestly I don't know why this works, but it does. Maybe somebody else can fill in the gaps for me. What I did was instead of trying to filter my list, I changed the filter function to return an array, and I use that result for ng-repeat to iterate.
Old filter function
$scope.filterByName = function(n) {
var name = n.name.toLowerCase();
var search = $scope.search.toLowerCase();
return name.indexOf(search) > -1;
};
New filter function
$scope.filterByName = function(list, srch) {
var ret = [];
_.each(list, function(l) {
if (l.name.toLowerCase().indexOf(srch.toLowerCase()) > -1) {
ret.push(l);
}
});
return ret;
};
Old ng-repeat
<li ng-repeat="s in scripts|filter:filterByName">
New ng-repeat
<li ng-repeat="s in filterByName(scripts, search)">

list not displaying in angular binding?

I am trying my first angular js list example. Having issues displaying the list, there are no errors in the console:(
html
<body ng-controller="mycontroller">
<form ng-submit="addtask()">total nr of tasks: {{myvar.length}}
<br />remaining: {{remaining()}}
<input type="text" ng-model="newtask" />
<ul ng-repeat="var in myvar">
<li>
<input type="checkbox" ng-model="myvardone" /> <span class="done-{{myvardone}}">{{var.text}}</span>
</li>
</ul>
<button type="submit">add</button>
</form>
</body>
script:
function mycontroller($scope) {
$scope.myvar = [{
text: 'bert',
done: false
}, {
text: 'ed',
done: true
}, {
text: 'pet',
done: false
}];
$scope.addtask = function () {
$scope.myvar.push({
text: $scope.newtask,
done: false
});
}
$scope.remaining = function () {
var count = 0;
angular.forEach($scope.myvar, function (t) {
if (t.done) {
count++
} else {
count += 0;
}
});
return count;
}
}
jsfiddle:http://jsfiddle.net/dingen2010/vc2bC/3/
simple demo can be like
<html ng-app>xxxxx</html>
don't forget "ng-app"
Several things
One. missed ng-app
Two. You should not repeating ul, but li
<li ng-repeat="var in myvar">
<input type="checkbox" ng-model="var.done" />
<span class="done-{{var.done}}">{{var.text}}</span>
</li>
Three. when you add, you need to have task name entered.
Four, you don't need remaining function. use filter
{{ (myvar | filter:{done:true}).length }}
http://jsfiddle.net/vc2bC/10/
Darn, Awakening beat me to it... :/ But yeah, just simply move the ng-controller tag to a containing and put a ng-app tag on the html tag. Here:
enter code herehttp://jsfiddle.net/vc2bC/8/

Resources