AngularJS displays only elements that meet a certain condition - angularjs

in my ng-repeat list I am displaying object elements from an object array $scope.toBuy:
$scope.toBuy=[
cookies={
name:'cookies',quantity:0,bought:false
},
water={
name:'water',quantity:0,bought:false
},
bananas={
name:'bananas',quantity:0,bought:false
},
milk={
name:'milk',quantity:0,bought:false
},
coconut={
name:'coconut',quantity:0,bought:false
}
];
and I initialize all element's bought field to false. How do I display in a ng-repeat list that only shows elements that have false value in their bought field? I tried this:
<ul>
<li ng-repeat="item in toBuy | filter:{item.bought===false }">Buy 10 {{item.quantity}} {{item.name}} <button class="btn btn-default" ng-click="btnOnClick(item.name)"> Bought</button></li>
</ul>
but none of the elements displayed when the page is loaded. If I removed the filter, the whole list displays, which means I applied the filter wrong.

You are using invalid javascript object syntax {item.bought===false }
Change to
ng-repeat="item in toBuy | filter:{bought:false }"
DEMO

Your JSON is not a valid JSON.
Try this valid JSON :
[{
"name": "cookies",
"quantity": 0,
"bought": true
}, {
"name": "water",
"quantity": 0,
"bought": true
}, {
"name": "bananas",
"quantity": 0,
"bought": true
}, {
"name": "milk",
"quantity": 0,
"bought": false
}, {
"name": "coconut",
"quantity": 0,
"bought": false
}]
Working demo :
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function($scope) {
$scope.toBuy=[{
"name": "cookies",
"quantity": 0,
"bought": true
}, {
"name": "water",
"quantity": 0,
"bought": true
}, {
"name": "bananas",
"quantity": 0,
"bought": true
}, {
"name": "milk",
"quantity": 0,
"bought": false
}, {
"name": "coconut",
"quantity": 0,
"bought": false
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<ul>
<li ng-repeat="item in toBuy | filter : {bought:false}">Buy 10 {{item.quantity}} {{item.name}} <button class="btn btn-default" ng-click="btnOnClick(item.name)"> Bought</button></li>
</ul>
</div>

Use ng-if (or ng-show):
<div ng-repeat="item in toBuy">
<div ng-if="item.bought===false">
Buy 10 {{item.quantity}} {{item.name}}
</div>
</div>

Try this:
<li ng-repeat="item in toBuy | filter:item.bought==false">
Or
<li ng-repeat="item in toBuy | filter:{bought:false}">
Will work, the second is a better way to achieve this.

Related

what version of UI bootstrap works with Angular 1.6.4?

I am using AngularJS v1.6.4 and bootstrap version is v3.3.4 and ui-bootstrap v2.5.0. I'm trying to use dropdown button but its not working but when using AngularJS v1.5.11 and bootstrap version is v3.3.4.Button dropdown is working.
<ul class="heroes" ng-repeat="role in names">
<li ng-if="role.accessMethod == 1">
<button type="button" class="btn btn-primary" uib-dropdown-toggle ng-disabled="disabled">
<span class="badge">{{role.code}}</span>
</button>
</li>
<li ng-if="role.accessMethod == 2">
<div class="btn-group" uib-dropdown>
<button type="button" class="btn btn-primary" uib-dropdown-toggle ng-disabled="disabled">
<span class="badge">{{role.code}}</span> <span class="caret"></span><span class="sr-only"></span>
</button>
<ul class="dropdown-menu" uib-dropdown-menu role="menu">
<li ng-repeat="roledetail in role.roles" ng-click="onSelect(roledetail.roleName)">
{{roledetail.roleName}}
</li>
</ul>
</div>
</li>
</ul>
and the json for it is
$scope.names = [{
"code": "abc",
"name": null,
"accessMethod": "1",
"roles": [{
"roleId": 1,
"roleName": "A"
},
{
"roleId": 3,
"roleName": "B"
}
]
}, {
"code": "XYZ",
"name": null,
"accessMethod": "2",
"roles": [{
"roleId": 1,
"roleName": "A"
},
{
"roleId": 3,
"roleName": "B"
}
]
}, {
"code": "Neo",
"name": null,
"accessMethod": "2",
"roles": [{
"roleId": 1,
"roleName": "A"
},
{
"roleId": 3,
"roleName": "C"
}
]
}, {
"code": "LAB",
"name": null,
"accessMethod": "1",
"roles": [{
"roleId": 1,
"roleName": "A"
},
{
"roleId": 3,
"roleName": "B"
}
]
}];
In the above code i'm trying to use different buttons based on access Method one is simple button when access method is 1 and another is button dropdown when access method is 2.When i'm using angular version 1.6.4 with bootstrap version 3.3.4 and uI-bootstrap version 2.5.0 i'm unable to get button dropdown

Cant display data from array in AngularJS

I have a problem with the print out Data from the array.
I have
{{orders}} =
[{"item":"DELL","quantity":6,"price":144},
{"item":"Samsung","quantity":3,"price":3131},
{"item":"222222","quantity":1,"price":31},
{"item":"111111111","quantity":1,"price":13}]
I try in View
<div ng-repeat="order in orders track by $index">
<span>{{ order[$index].item }}
</span>
</div>
And nothing. Can someone help me with that??
Edit:
Still does not work
{{orders}}
<div ng-repeat="order in orders track by $index">
<span>
{{order.item}}
</span>
and nothing
controller:
$scope.ListOfOrders = function () {
return ApiService.cart.list().then(function (resp) {
$scope.orders = resp[0].order;
console.log(resp[0].order)
});
}
UI
<div ng-repeat="order in orders track by $index">
<span>{{order.item}}</span>
</div>
Controller
$scope.orders = [{
"item": "DELL",
"quantity": 6,
"price": 144
}, {
"item": "Samsung",
"quantity": 3,
"price": 3131
}, {
"item": "222222",
"quantity": 1,
"price": 31
}, {
"item": "111111111",
"quantity": 1,
"price": 13
}]
Working Solution
You don't need to bind order[$index], ng-repeat itself iterates over every object so just write :
<div ng-repeat="order in orders track by $index">
<span>{{ order.item }}
</span>
</div>

angularjs - how to use ng-repeat element to get data from another set of data

Sorry, the titles is not clear at all, but I didn't really know a better title to explain what I'm tring to do.
Basically, I've this set of data:
$scope.data = [
{"id": 0, "name": "Testing name 0", "type": 1, "details": {"pinned": true, "link": [1,2]}},
{"id": 1, "name": "Testing name 1", "type": 0, "details": {"pinned": true, "link": [4]}},
{"id": 2, "name": "Testing name 2", "type": 0, "details": {"pinned": true, "link": []}},
{"id": 3, "name": "Testing name 3", "type": 0, "details": {"pinned": true, "link": []}},
{"id": 4, "name": "Testing name 4", "type": 1, "details": {"pinned": true, "link": [4,0]}},
{"id": 5, "name": "Testing name 5", "type": 1, "details": {"pinned": true, "link": []}},
{"id": 6, "name": "Testing name 6", "type": 1, "details": {"pinned": true, "link": [1,2,3,4]}}
];
and this repeater to display only the rooms with type 1:
<ion-list class="list">
<div ng-repeat="item in data">
<ion-item class="item item-stable" ng-if="item.type==1">
{{item.name}}
</ion-item>
<div ng-if="item.type==1" ng-repeat="(key, value) in item.details">
<div ng-repeat="linkID in value" ng-if="key == 'link'">
<ion-item class="item-accordion">
{{linkID}}
</ion-item>
</div>
</div>
</div>
</ion-list>
as you can see from the code above, I'm printing a top level item with the name of all "type:" 1, and as a sublevel, all off the values inside link: [].
So far so good, but the values inside link: [] are IDs of linked posts, and instead of 1,2 or 3 I'd like to print "Testing name 1", "Testing name 2", "Testing name 3" and so on...
I can't figure out the best way. All the data is there, but I just can't display it. I tried with another ng-if, but nothing. Any help?
here's an example: http://codepen.io/nickimola/pen/dMNawj?editors=1010
Instead of using ng-if better use filter.
Live example on jsfiddle.
angular.module('ExampleApp', [])
.controller('ExampleController', function($scope) {
$scope.data = [{
"id": 0,
"name": "Testing name 0",
"type": 1,
"details": {
"pinned": true,
"link": [1, 2]
}
}, {
"id": 1,
"name": "Testing name 1",
"type": 0,
"details": {
"pinned": true,
"link": [4]
}
}, {
"id": 2,
"name": "Testing name 2",
"type": 0,
"details": {
"pinned": true,
"link": []
}
}, {
"id": 3,
"name": "Testing name 3",
"type": 0,
"details": {
"pinned": true,
"link": []
}
}, {
"id": 4,
"name": "Testing name 4",
"type": 1,
"details": {
"pinned": true,
"link": [4, 0]
}
}, {
"id": 5,
"name": "Testing name 5",
"type": 1,
"details": {
"pinned": true,
"link": []
}
}, {
"id": 6,
"name": "Testing name 6",
"type": 1,
"details": {
"pinned": true,
"link": [1, 2, 3, 4]
}
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="ExampleApp">
<div ng-controller="ExampleController">
<ion-list class="list">
<div ng-repeat="item in data|filter:{type:1}">
<ion-item class="item item-stable">
{{item.name}}
</ion-item>
<div ng-repeat="linkID in item.details.link">
<ion-item class="item-accordion">
Lnked post--{{data[linkID].name}}
</ion-item>
</div>
<div ng-show="item.details.link.length==0">
<i>Nothing linked</i>
</div>
</div>
</ion-list>
</div>
</div>
Think that is what you expected?
<ion-content ng-app="ionicApp" ng-controller="MyCtrl">
<ion-list class="list">
<div ng-if="item.type==1" ng-repeat="item in data">
<ion-item class="item item-stable">
{{item.name}}
</ion-item>
<div ng-repeat="link in item.details.link">
<ion-item ng-if="data[link].name" class="item-accordion">
{{data[link].name}}
</ion-item>
<ion-item ng-if="!data[link].name" class="item-accordion">
Link not found: {{link}}
</ion-item>
</div>
<ion-item ng-if="item.details.link.length == 0">
Nothing
</ion-item>
</div>
</ion-list>
</ion-content>
You could load the links into the scope then reference them with the id (assuming they're in order).
<div ng-repeat="linkID in value" ng-if="key == 'link'">
<ion-item class="item-accordion">
{{links[linkID]}}
</ion-item>
</div>

AngularJS ng-repeat for a JSON contains String or an array of a same property

I'm having a JSON data namely $scope.family, it contains the family.name and optionally family.child
app.controller('test', function ($scope) {
$scope.family = [
{
"name": "Siva",
"child": [
{
"name": "Suriya"
},
{
"name": "Karthick"
}
]
},
{
"name": "Kumar",
"child": [
{
"name": "Rajini"
},
{
"name": "Kamal"
},
{
"name": "Ajith"
}
]
},
{
"name": "Samer",
"child": "Ranjan"
},
{
"name": "Mahesh",
"child": "Babu"
},
{
"name": "Joseph"
}
];
});
Cases:
If family.child has one child then the name is directly assign as a string
If family.child has more than one child then the name is assign as a array of string with the property family.child.name
If family.child doesn't in the collection just show the family.name
My Expected Output UI is
Siva
Suriya
Karthick
Kumar
Rajini
Kamal
Ajith
Samer
Ranjan
Mahesh
Babu
Joseph
My HTML Source Code (I Can't able to get the expected output from this code)
<ul>
<li ng-repeat="member in family">
{{ member.name }}
<div class="liststyling" ng-if="member.child.length > 0">
<ul>
<li ng-repeat="chdMember in member.child>
{{ chdMember.name }}
</li>
</ul>
</div>
</li>
</ul>
Kindly assist me...
Please refer the fiddle here. You need some changes in the model and loop with the new modified model - newFamily instead of family.
HTML:
<div ng-app="app" ng-controller="test">
<ul>
<li ng-repeat="member in newFamily">
{{ member.name }}
<div class="liststyling" ng-if="member.child.length > 0">
<ul>
<li ng-repeat="chdMember in member.child track by $index">
{{ chdMember.name }}
</li>
</ul>
</div>
</li>
</ul>
</div>
JS:
var app = angular.module('app', []);
app.controller('test', function ($scope) {
$scope.family = [
{
"name": "Siva",
"child": [
{
"name": "Suriya"
},
{
"name": "Karthick"
}
]
},
{
"name": "Kumar",
"child": [
{
"name": "Rajini"
},
{
"name": "Kamal"
},
{
"name": "Ajith"
}
]
},
{
"name": "Samer",
"child": "Ranjan"
},
{
"name": "Mahesh",
"child": "Babu"
},
{
"name": "Joseph"
}
];
$scope.newFamily = [];
angular.forEach($scope.family, function (v, k) {
var existingChildArray = v.child;
var newChildArray = [];
if (!angular.isArray(v.child) && v.child) {
newChildArray.push({ 'name': v.child });
}
var addChild = newChildArray.length > 0 ? newChildArray : existingChildArray;
$scope.newFamily.push({ 'name': v.name, 'child': addChild });
});
});
Try this for your actual output.
<ul>
<li ng-repeat="member in family">
{{ member.name }}
<div class="liststyling">
<ul>
<li ng-repeat="chdMember in member.child">
{{ chdMember.name }}
</li>
</ul>
</div>
</li>
</ul>
$scope.family = [
{
"name": "Siva",
"child":
[
{
"name": "Suriya"
},
{
"name": "Karthick"
}
]
},
{
"name": "Kumar",
"child": [
{
"name": "Rajini"
},
{
"name": "Kamal"
},
{
"name": "Ajith"
}
]
},
{
"name": "Samer",
"child": [{name:"Ranjan"}]
},
{
"name": "Mahesh",
"child": [{name:"Babu"}]
},
{
"name": "Joseph",
"child": []
}
];
You can add the following method to your controller
$scope.isArray = function(obj) {
return angular.isArray(obj);
}
and update the markup as
<li ng-repeat="member in family">
{{ member.name }}
<div class="liststyling">
<ul ng-if="isArray(member.child)">
<li ng-repeat="chdMember in member.child">
{{ chdMember.name }}
</li>
</ul>
<ul ng-if="member.child && !isArray(member.child)">
<li>
{{ member.child }}
</li>
</ul>
</div>
</li>
This should do, I think.
Even though #MarcNuri provided a good answer. But if you are not changing the data pattern you can use this also.
HTML
<ul>
<li ng-repeat="member in family">
{{ member.name }}
<div class="liststyling" ng-if="isArray(member.child) && member.child.length > 0">
<ul>
<li ng-repeat="chdMember in member.child">
{{ chdMember.name }}
</li>
</ul>
</div>
<div class="liststyling" ng-if="!isArray(member.child) && member.child.length > 0">
<ul>
<li>
{{ member.child}}
</li>
</ul>
</div>
</li>
</ul>
JS
app.controller('test', function ($scope) {
$scope.isArray = angular.isArray;
$scope.family = [
{
"name": "Siva",
"child": [
{
"name": "Suriya"
},
{
"name": "Karthick"
}
]
},
{
"name": "Kumar",
"child": [
{
"name": "Rajini"
},
{
"name": "Kamal"
},
{
"name": "Ajith"
}
]
},
{
"name": "Samer",
"child": "Ranjan"
},
{
"name": "Mahesh",
"child": "Babu"
},
{
"name": "Joseph"
}
];
});
just notice $scope.isArray = angular.isArray; in js.Find plank HERE
Here is a simple running version of your code JSFiddle (not the best coding practices)
Keep in mind that you should use at least AngularJS 1.1.15 version at least to use ng-if.
You should simply tidy up your script a little and it'll work:
HTML:
<body ng-app="myApp">
<div ng-controller="ctrl">
<ul>
<li ng-repeat="member in family">
<h2>
{{ member.name }}
</h2>
<div class="liststyling" ng-if="member.child.length > 0">
<ul>
<li ng-repeat="chdMember in member.child">
{{ chdMember.name }}
</li>
</ul>
</div>
</li>
</ul>
</div>
</body>
Javascript:
var app = angular.module('myApp',[]);
app.controller('ctrl', MyCtrl);
function MyCtrl($scope) {
$scope.family = [
{
"name": "Siva",
"child": [
{
"name": "Suriya"
},
{
"name": "Karthick"
}
]
},
{
"name": "Kumar",
"child": [
{
"name": "Rajini"
},
{
"name": "Kamal"
},
{
"name": "Ajith"
}
]
},
{
"name": "Samer",
"child": [{name:"Ranjan"}]
},
{
"name": "Mahesh",
"child": []
},
{
"name": "Joseph"
}
];
}

AngularJS sorting by field value

What I am trying to do is sort some data by field value.
$scope.testarr = [{"id":"1","name":"coffee"},
{"id":"2","name":"tea"},
{"id":"3","name":"coffee"},
{"id":"4","name":"ice coffee"}]
in the html file i have select box and 3 options called coffee, tea and ice coffee,
if i select coffee should be sorted like this
$scope.testarr = [{"id":"1","name":"coffee"},
{"id":"3","name":"coffee"},
{"id":"2","name":"tea"},
{"id":"4","name":"ice coffee"}]
if i select tea should be sorted like this
$scope.testarr = [
{"id":"2","name":"tea"},
{"id":"1","name":"coffee"},
{"id":"3","name":"coffee"},
{"id":"4","name":"ice coffee"}]
i'm trying to use order by but somehow it does't work
<div ng-repeat="item in testarr | orderBy: 'name'">
{{item.id}} ------ {{item.name}}
</div>
It does seem to work. Ensure that your ng-repeat has access to $scope.testarr (i.e. it is being declared on your $scope in the correct controller or directive.
angular.module('app', [])
.controller('ctrl', function($scope) {
$scope.testarr = [{
"id": "1",
"name": "coffee"
}, {
"id": "2",
"name": "tea"
}, {
"id": "3",
"name": "coffee"
}, {
"id": "4",
"name": "ice coffee"
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="ctrl">
<div ng-repeat="item in testarr | orderBy: 'name'">
{{item.id}} ------ {{item.name}}
</div>
</div>
</div>

Resources