ng-if and ng-repeat to compare in table - angularjs

I have a table with id column (1,2,3,4,5) and i have an array of elements. $scope.elements has values - 1,3.
<ul ng-repeat="x in elements>
<li>{{x}}</li>
</ul>
Using this I have to compare the values inside elements array with id in a table. If both idd matches I have to hide that row.
When I use ng-if, since I use ng-repeat multiple rows are getting created for each iteration...
can anyone help me to solve this issue...
UPDATE:
hides2 = [1,3,4]
ng-repeat="x in [hides2] track by $index" ng-if="x!=3"
But the table shows the values, (its not hiding 1,3,4 records)
[enter image description here]1

I don't knnow how you are using ng-if but it's very simple to use, here's is an simple example
angular.module("app",[]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<body ng-app="app">
<div ng-repeat="item in [1,2,3,4,5,6,1,2,4,5] track by $index" ng-if="item !== 1">{{item}}</div>

Here try this.. create a function in controller as following
$scope.elements = [1,2,3,4,5];
$scope.checkMatch = function(id){
if($scope.elements.indexOf(id) !== -1){
return true;
}else{
return false;
}
}
In you template call this method in ng-if as following and pass the id in checkMatch...
<ul ng-repeat="x in elements>
<li ng-if="checkMatch(x)">{{x}}</li>
</ul>

Related

data-ng-repeat: how to set different options according to the index

Sorry if this look like a stupid question but I have just started using angular.js and certain things are not easy to catch.
I have a list of numbers which I am showing using this:
<li data-ng-repeat="i in getNumber(list) track by $index" data-ng-click="myFunction($index)" data-ng-class="myClass">{{$index+1}}</li>
This is showing my list as 1 2 3 4 5 etc
I'd like to change this to show something different upon reaching a specific index, i.e.
if index == 5 then show ABCD instead of {{$index+1}}
Is it something I can achieve with ng-repeat or do I need to use a different approach?
Thanks a lot for the input
You can achieve it inside the interpolation markup {{...}} only, as we can do all normal javascript operations inside it:
var app = angular.module('myApp', []);
app.controller('AppCtrl', function($scope) {});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<section ng-app="myApp">
<div ng-controller="AppCtrl">
<li data-ng-repeat="i in [1,2,3,4,5,6,7] track by $index">
{{ $index === 5 ? 'ABCD' : $index+1 }}
</li>
</div>
</section>

Not able to fetch the json data using angularjs

Here is the plunker link. I am trying to fetch the json data using Angularjs where data is like object of objects of array.
Plunker link with example
You need to iterate it over key and value in ng-repeat. check plunker
like
<div ng-repeat="(key, value) in questions">
{{key}}
<div ng-repeat="item in value">
version : {{item.version}}
</div>
</div>
your div tag is not closed properly....
<div ng-repeat="ques in questions">
<p>{{ques[0].version}}</p>
</div>
your ng-repeat div tag was closed before your tag.
Fixed Plunker Link
Plunker: for each sub version
Some code modifications as components properties are dynamic. hence, iterate it dynamic :
$scope.components = response.data.components;
$scope.questions = [];
for(var i in Object.keys($scope.components)) {
for(var j in $scope.components[Object.keys($scope.components)[i]]) {
$scope.questions.push($scope.components[Object.keys($scope.components)[i]][j]);
}
}
console.log($scope.questions);
});
updated Plnkr : https://plnkr.co/edit/PuvO6PrifWa5WtpeQrvY?p=preview

$index does not diminish its value when ng-if removes an element

My HTML:
<section ng-repeat="Rule in Data track by $index" ng-if="!Rule.is_deleted">
{{$index}}
{{ Rule.title }}<a ng-click="removeElem($index)"></a>
</section>
and the controller:
$scope.removeElem = function (elemIndex) {
$scope.Data[elemIndex].is_deleted = true;
}
$scope.addElem = function(obj) {
$scope.Data.push(obj);
}
There is a functionality of adding/removing objects to/from $scope.Dataarray. Let's say there are two items in $scope.Data; I am removing one and add a new one. Therefore, the items are still two. The problem is that $index associates the newly created second item with value 2 and not value 1 as I expected (ng-if removes the item from the DOM, isn't it?). Why that? How may I oblige $index to diminish its value if removing an item?
You probably want to filter rather than using ng-if in the ng-repeat.
<section ng-repeat="Rule in (Data | filter: {is_deleted: false}) track by $index">
{{$index}}
{{ Rule.title }}<a ng-click="removeElem($index)"></a>
</section>
fiddle showing the difference: https://jsfiddle.net/u6nqrq5o/
Don't use $index for this, just pass the object to the function. Also, this is a better use case for a filter rather than using ng-if to hide/show a row
HTML
<section ng-repeat="Rule in Data | filter: {is_deleted: false}">
{{ Rule.title }}
<a ng-click="removeElem(Rule)">Remove</a>
</section>
Controller
$scope.removeElem = function(rule) {
rule.is_deleted = true;
};
Using $index should be avoided.Instead of using $index, prefer to pass the actual objects around. E.g. ng-click="removeElem(Rule)"

Sorting elements in AngularJS for nested ng-repeat

I am using bootstrap to display a grid of projects with each row having 3 columns. In order to accomplish this, I am using ng-repeat twice like below.
<div class="row" ng-repeat="chunk in projects">
<div class="col-sm-4" ng-repeat="project in chunk | orderBy:'title'">
{{project.title}}
</div>
</div>
I want to be able to sort the project based on its title field. Applying a filter only sorts a subset of the whole list i.e. sorts at the chunk level rather than the projects level.
var projects = [[{"title":"Z"},{"title":"A"},{"title":"M"}],
[{"title":"Z"},{"title":"A"},{"title":"M"}]];
After the orderBy happens, the rows are A M Z, A M Z. How do I get it to display A A M, M Z Z?
Here is the plunk for the above problem.
//EDIT : The above plunk points to the solution because I updated the plunk.
You'll need a custom filter that will turn your sub-arrays into a single array. The whole point of having separate arrays would be to isolate the contents, which is the opposite of what you want.
Filter:
yourAppModule
.filter('titleSort', function(){
return function(input){
var fullArray = []; //Will be the output array
for(var i=0;i<input.length;i++)
fullArray.concat(input[i]);
//Iterates through all the arrays in input (projects)
//and merges them into one array
fullArray = fullArray.sort(function(a,b){return a.title>b.title});
//Sorts it by the title property
var chunks = [];
var currentChunk;
for(var i=0;i<fullArray.length;i++){
if(i%3===0){
currentChunk = [];
chunks.push(currentChunk);
}
currentChunk.push(fullArray[i]);
}
return chunks;
};
} ...
Now your view can be this:
<div class="col-sm-4" ng-repeat="project in projects | titleSort">
{{project.title}}
</div>
I was able to solve this problem finally through filter chaining. I used angular-filter module/library but this can be even done without angular-filter.
<div class="container" ng-controller="ExampleController as exampleVm">
<div class="row" ng-repeat="chunk in exampleVm.projects| chunkBy: 'title' | groupBy : 3">
<div class="col-sm-4" ng-repeat="project in chunk">
{{project.title}}
</div>
</div>
I flattened the array and made it look like this.
var projects = [{"title:Z"},{"title":"A"},{"title":"M"},{"title:Z"},{"title":"A"},{"title":"M"}]
In the filter chain, I order the elements in the flattened array first by title and then divide it into subarrays of 3 elements each. Hope this helps.
You can find the plunk here.
try this. may be help you.
var app = angular.module("app",[])
app.controller('ctrl',['$scope', function($scope){
$scope.data = [[{"title":"Z"},{"title":"A"},{"title":"M"}],
[{"title":"Z"},{"title":"A"},{"title":"M"}]];
$scope.data2 = [];
angular.forEach( $scope.data,function(d){
angular.forEach(d,function(d1){
$scope.data2.push(d1);
})
})
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<div ng-app="app" ng-controller="ctrl">
<div class="item item-checkbox">
<div class="row">
<div class="col-sm-4" ng-repeat="project in data2 | orderBy:'title'">
{{project.title}}
</div>
</div>
</div>

How to reverse an array in angular js without creating a filter

I am having an array in controller as follows
function FooController($scope) {
$scope.items = ["a","b","c"];
}
I used ng-repeat to show the data in items,
<div ng-app>
<div ng-controller="FooController">
<ul ng-repeat="item in items">
<li>{{item}}</li>
</ul>
</div>
</div>
I got the result as a,b,c order. I want to show it in reverse order. that means c,b,a without changing its order in the controller or without creating a filter. How to do that?
Check this link
I faced the same problem, but with an array of objects. This quick solution worked for me, but using the filter is still the best practice.
<li data-ng-repeat="item in data.slice().reverse()">
...
</li>
http://bootply.com/SgVBZvZ708
In order to avoid the writting of a custom filter, I suggest you to use this syntax :
<ul ng-repeat="item in items | orderBy:'-toString()'">
The documentation assume you sort an array of Objects but in your case there are just plain strings.
Wrap the strings in objects and use orderBy or create a new filter:
angular.module("app",[])
.filter("reverse", function(){
return function(items){
return items.slice().reverse(); // Create a copy of the array and reverse the order of the items
};
});
And use it like this:
<ul ng-repeat="item in items|reverse">
Updated fiddle (I've also updated the ng-app directive so it's passed the "app" module.)

Resources