Cannot print current value in ng-repeat - angularjs

Here is my code:
codepen.io/bedtvapp/pen/NMoBby
<div ng-app="app">
<h1>AngularJS Directive Controllers</h1>
<div ng-init="count1 = 1"></div>
<div ng-repeat-start="a in [1, 2, 3, 4, 5]" ng-init="$parent.count1 = $parent.count1 + 1"></div>
<div>
abc {{ a }} - {{::$parent.count1}} </div>
<div ng-if="$parent.count1 % 2 == 0">breakline</div>
<div ng-repeat-end></div>
</div>
I want to count item in array into custom variable (count1) (not $index). Because I will add more condition to my counting later.

If you just want to print count then just do following changes in your code
<div ng-app="app">
<h1>AngularJS Directive Controllers</h1>
<div ng-repeat-start="a in [1, 2, 3, 4, 5]" ></div>
<div>
abc {{ a }} - {{$index + 1}} </div>
<div ng-repeat-end></div>
</div>
You no need to do any initalization thing

If you increment count1 in ng-repeat-start init, end of the repeat count1 have the same value. So you need to get the help of $index. You can use count1 for the set starting value.
You can simply achieve your target using bellow code
<div ng-init="count1 = 1"></div>
<div ng-repeat-start="a in [1,2,3,4,5]" >
abc{{a}}- {{count1+$index+1}}
</div>
<div ng-if="(count1+$index+1) % 2 == 0">breakline</div>
<div ng-repeat-end></div>
output like this,
abc1- 2
breakline
abc2- 3
abc3- 4
breakline
abc4- 5
abc5- 6
breakline
If you want to add more condition you need based on (count1+$index+1) value.

Related

HTML div formatting not resulting in desired output

I have two an array with two sets of data and I want to display each set in a separate column, in the following format:
Set1 Set 2
1 ABC
2 DEF
GEF
3 HIJ
JKL
4 MNO
PQR
Instead, my data appears as follows:
Set 1 Set 2
1 ABC
2 DEF
GEF 3
HIJ
JKL 4
MNO
PQR
How do I make my data appear correctly (ie, make sure all data from Set 2 falls in the right column) using the tag, assigning "class = col-xs-4" to the first set and "class= col-xs-8" to the second? Here's my code as it stands now:
<div ng-switch="hoursOfOp[0]">
<div ng-switch-when = "Not available"><class="col-xs-4 align-right">{{hoursOfOp[0]}}</div>
<div ng-switch-default>
<div ng-repeat="hours in hoursOfOp">
<div class="col-xs-4 align-left">{{hours.day}}</div>
<div class="col-xs-8 align-left no-padding" ng-repeat="time in hours.time">{{time}}</div>
</div>
</div>
</div>
As I said in the comment, that's because when a col does not fit on the same row, it goes to the next one. What you can do is to make another div inside the div with col-xs-8 and put the ng-repeat there, as a list or something.
Keep in mind that ng-repeat repeats the element it is put in. So in your case, the flow is the following:
creates the col-xs-4 with the 1 value on first row
creates the col-xs-8 with the ABC value on first row, since there is space
creates the col-xs-4 with the 2 value on the next row, because there isn't space above
creates the col-xs-8 with the DEF value on the same row, since there is space
creates the col-xs-8 with the GEF value on the NEXT ROW, since there isn't space above
from this point, everything gets messed up.
The below example is working :)
var app = angular.module("myApp", []);
app.controller('testCtrl', ['$scope', function ($scope) {
$scope.hoursOfOp = [
{id: 1, time: ["ABC"]},
{id: 2, time: ["DEF", "GEF"]},
{id: 3, time: ["HIJ", "JKL"]},
{id: 4, time: ["MNO", "PQR"]}]
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css" integrity="sha384-AysaV+vQoT3kOAXZkl02PThvDr8HYKPZhNT5h/CXfBThSRXQ6jW5DO2ekP5ViFdi" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js" integrity="sha384-3ceskX3iaEnIogmQchP8opvBy3Mi7Ce34nWjpBIwVTHfGYWQS9jwHDVRnpKKHJg7" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.3.7/js/tether.min.js" integrity="sha384-XTs3FgkjiBgo8qjEjBk0tGmf3wPrWtA6coPfQDfFEY8AnYJwjalXCiosYRBIBZX8" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/js/bootstrap.min.js" integrity="sha384-BLiI7JTZm+JWlgKa0M0kGRpJbF2J8q+qreVrKBC47e3K6BW78kGLrCkeRX6I9RoK" crossorigin="anonymous"></script>
<div ng-app="myApp">
<div ng-controller="testCtrl">
<div ng-repeat="hours in hoursOfOp" class="row">
<div class="col-xs-4 col-md-4 stuff">{{ hours.id }}</div>
<div class="col-xs-8 col-md-8 stuff">
<div ng-repeat="v in hours.time">
{{ v }}
</div>
</div>
</div>
</div>
</div>

Angular 5 loop array

I am really a beginner in angular ionic and stuff. Here, my problem is I have tried using *ngFor to iterate someArr and pass to [something]="" but my page became blank after adding it. Can someone help me.
someArr = [1, 2, 3, 4, 5, 6]
<ion-content>
<myHeader *ngIf="qArr.length && qArr[cPg].letter === 'A'" [something]="">
</myHeader>
<myHeader *ngIf="qArr.length && qArr[cPg].letter === 'B'" [something]="">
</myHeader>
</ion-content>
When using ngFor you are creating local variable based on a class variable so you will have something like :
<div *ngFor="let item of someArr"></div>
where someArr is the class var = [1, 2, 3, 4, 5, 6]
So inside your div, you will have access to each item using this :
<div *ngFor="let item of someArr">
<p *ngIf="item === myFunction(item)"> {{ item }} </p>
</div>
Can you show what you've tried with ngFor?
Should looks something like this
<div *ngFor="let val of someArr">
{{val}}
</div>
Sidenote, you cannot combine ngFor and ngIf inside same tag
meaning this will not work
<div *ngFor="let val of someArr" *ngIf="val === 1">
{{val}}
</div>
But this would work
<div *ngFor="let val of someArr">
<div *ngIf="val === 1">
{{val}}
</div>
</div>
Update
something is not a real attribute, so we have no idea what you're refering to.
However you should be able to assign values to attribute. Take id attribute for instance
<div *ngFor="let val of someArr">
<div [id]="val">
{{val}}
</div>
</div>

Angularjs ng-repeat iterate by 2

I have a for loop in my MVC application like this
for(var i = 0; i < data.length; i +=2){
<div class='#(i== 0? "item active": "item")'>
<div>
#Html.Raw(data[i].Description)
</div>
<div>
#Html.Raw(data[i + 1].Description)
</div>
</div>
}
I want to convert the above code in angularjs.
Means every loop render the record from current and next array index, say i = 0 then render first and second record detail.
Actually it is big object, for clarity I reduce the code, I want to write the same code in ng-repeat
See the fiddle
I end up with a dirty trick:
<div ng-repeat="item in data"
ng-class="{active: $first}" class="item row"
ng-if='$index % 2 == 0'>
<div class='col-lg-6'>{{ item.a }}</div>
<div class='col-lg-6'>{{ data[$index + 1].a }}</div>
</div>
If $index % 2 == 0 only then render, means 0, 2, 4 .. it work as I want.
See to codepen.
You essentially want something like this:
<div ng-repeat="dataEntry in data" ng-class="{active: $first}" class="item">
<div>{{ dataEntry.Description }}</div>
<div ng-if="!$last">{{ data[$index + 1].Description }}</div>
</div>
Use ng-repeat to loop over your data entries
Use ng-class to only apply 'active' class to the first entry (you have access to $first, $last, $even, and $odd, (which are booleans) inside of an ng-repeat scope)
dataEntry represents each entry for each iteration of your data. Use {{ }} to access and render it's contents
You can use $index + 1 to grab the next entry in the array of entries.
I would assume you know that data in this scenario has to be attached / accessible from your $scope.

Angular js - how to increment in html based on condition

I am using angular repeat to populate form's fields dynamically. There is a scenario where I need to to notify user(show ! icon for duplicate fields). Below is code snippet:
<div ng-init="counter = 0">
<div ng-repeat="item in list track by $index">
<div ng-show="{{item.show}}">{{counter+1}}</div>
</div>
<div ng-show="{{counter > 1}}"> ! </div>
</div>
Counter variable only increment if its used like {{counter + $index}}, can it be possible without $index?
Assigning variables inside html is not officially supported.
But there is always a hack for what you asked:
<div ng-init="counter = 0"></div>
<div ng-repeat="n in [1,2,3,4,5]">
<div style="display:none;">{{ n == 3 ? counter = "World!" : counter = n }}</div>
<p>Hello {{ counter }}</p>
</div>
Notice that I used a non-displayed div for assigning the "counter" conditionally.
Output:
Hello 1
Hello 2
Hello World!
Hello 4
Hello 5
Answer to the 1st comment:
When counter == 3, we divide it by 2.
<div ng-init="counter = 0"></div>
<div ng-repeat="n in [1,2,3,4,5]">
<div style="display:none;">
{{ counter = n }}
{{ counter == 3 ? counter = counter / 2 : counter = counter }}
</div>
<p>Hello {{ counter }}</p>
</div>
Output:
Hello 1
Hello 2
Hello 1.5
Hello 4
Hello 5
Answer to the 3rd comment:
I finally understood what you asked. Let me change the way to approach by using ng-if to keep the record of counter. I used ng-init to increment the counter when n is divisible by 2. You need to call $parent.$parent.counter to reach the original counter otherwise ng-if will create its own counter inside the child scope.
JSFiddle
<div ng-init="counter = 0"></div>
<div ng-repeat="n in [2,6,5,6,8,9,11] track by $index">
<!-- ngRepeat child scope -->
<div ng-if="n % 2 == 0"
ng-init="$parent.$parent.counter = $parent.$parent.counter + 1"
style="display:none;">
<!-- ngIf also creates a child scope -->
</div>
</div>
<p>Counter = {{ counter }}</p>
Output:
Counter = 4

How to pass a variable from view to scope using ngRepeat

I'm making a browse page where users can see the top terms for my site's search facets (I'm using ElasticSearch/Tire.) I created an array of objects with a title and arguments in the format I need for search. I want to iterate through the array and display the title and then the results of my search for each facet. At first I tried using a for loop in the controller to iterate through facet_selections, but that didn't seem like the Angular way. So now I'm trying to use ng-repeat for the iteration, but I'm not sure how to pass the arguments from the view to the controller. I read through all the directives, and I don't see a good fit, which makes me think I might be on the wrong path all together.
Here is a simplified controller:
$scope.facet_selections=[{name:"Collection", value: "collection_title", term: "collectionTitle"}, {name:"Series", value: "series_title", term: "seriesTitle"}, {name:"Episode", value: "episode_title", term: "episodeTitle"},];
$scope.frequency=Frequency.query({facet: facet}).then(function(data) {
$scope.topterms=data.facets[term].terms;
})
And here's the html:
<div class="browse" ng-repeat="object in facet_selections" ng-init="var term={{object.term}}">
<h4> {{object.name}} </h4>
<ul>
<li ng-repeat="term in topterms"> {{term.term}} ({{term.count}})</li>
</ul>
</div>
The problem is that you can't bind the html to a promise. You have to wait for the promise to resolve then update the scope. So I would handle the initial loop in the controller, not with an ng-repeat.
$scope.facet_selections=[{name:"Collection", value: "collection_title", term: "collectionTitle"}, {name:"Series", value: "series_title", term: "seriesTitle"}, {name:"Episode", value: "episode_title", term: "episodeTitle"},];
for(var i; i < $scope.facet_selections.length; i++){
var selection = $scope.facet_selections[i];
Frequency.query({facet: selection.value}).then(function(data) {
$scope.facet_selections[i].results = data.facets[selection.term].terms;
$scope.$digest() // hook into the angular binding system
});
}
then
<div class="browse" ng-repeat="facet in facet_selections">
<h4> {{facet.name}} </h4>
<ul>
<li ng-repeat="term in facet.results"> {{term.term}} ({{term.count}})</li>
</ul>
</div>
Passing arguments from the view to the controller is extremely easy:
$scope.numbers = [0, 4, 5, 2];
$scope.getTimesTwo = function(num){
return num * 2;
};
then
<div ng-repeat="num in numbers">
{{num}} <span>{{getTimesTwo(num)}}</span>
</div>
will result in
<div ng-repeat="num in numbers">
0 <span>0</span>
</div>
<div ng-repeat="num in numbers">
4 <span>8</span>
</div>
<div ng-repeat="num in numbers">
5 <span>10</span>
</div>
<div ng-repeat="num in numbers">
2 <span>4</span>
</div>
Its just that that is not really your problem, its promise resolution hooking to the $digest cycle

Resources