Angular ng-repeat $index - javascript

I'm creating a list of items the user can click to go to the next picture.
<ol class="indicators">
<li ng-repeat="img in pics" ng-click="slideTo($index)"></li>
</ol>
this code works but the problem is that it doesnt fill in the $index in the ngClick directive. This is the resulting html:
<li ng-repeat="img in pics" ng-click="slideTo($index)" class="ng-scope"></li>
if I put the $index in between {{ }}, it does work, but I get an error in the console.
Resulting html:
<li ng-repeat="img in pics" ng-click="slideTo(0)" class="ng-scope"></li>
Error:
Error: [$parse:syntax] http://errors.angularjs.org/1.3.15/$parse/syntax?p0=%7B&p1=invalid%20key&p2=10&p3=slideTo(%7B%7BNaNndex%7D%7D)&p4=%7B%index%7D%7D
I've seen examples of this where they dont use the curly brackets but then the $index was used in a child element and not the element itself.
Could someone tell me what I'm doing wrong and when you should use {{ }} when using Angular Expressions.

Inspector will not show it filled in, however, if you try logging the parameter passed to the function you will see that it is indeed the corresponding index number to the item you clicked on.

Related

Angular 1.4: How do I force update of directive within a ng-repeat with filter?

How does one force a directive to update if it nested in a ng-repeat which has a filter?
Input Box
<input type="text" class="name-search" ng-model="search.text">
HTML
<ul>
<li ng-repeat="user in users track by $index | filter:search">
<profile-photo user="user"></profile-photo>
<span>{{ user.name }}</span>
<li>
</ul>
As I type in the input box, the users filter properly but the profile-photo directive doesnt have the proper user.
Any help would be greatly appreciated!
Heres a dumbed down Plunker of my actual code. If you start typing, you will notice that it filters but the image doesnt update.
https://plnkr.co/edit/FWD2bFdIh7jQa5aqdkjrPlunker
your link's function code only executes once, when compiling the directive. After that, scope.photoUrl does not change even if you change the user, because you're not $watching the value. You can add a watch, or directly, use this in the template
ng-src="{{user.photoUrl}}"

Hide item that is part of a loop based on a condition

<ul *ngFor="#item of items; #i=index" >
<li [hidden]="{{ item.myattr === 'some_value' }}"> {{ item.val}} </li>
</ul>
I have the following code shown above. I want hide the list if the item has a value equal some value. In this case I have the items, they have an attribute called myattr, and if it is equal to some_value then the item should be hidden. The code I provided though does not work.
You don't need to use interpolation {{}} with property binding [] (actually, you can't):
<li [hidden]="item.myattr === 'some_value'">
Also, read Mistake #1: Binding to the native "hidden" property in http://angularjs.blogspot.com/2016/04/5-rookie-mistakes-to-avoid-with-angular.html
So a better solution is likely
<li *ngIf="item.myattr !== 'some_value'">
You can basically use ng-hide also like;
<li ng-hide="item.myattr =='some_value'"> {{item.val}} </li>
assuming that item.myattr is the same type with some_value.
I think is better to use pipe to filter out unneeded items.
https://angular.io/docs/ts/latest/guide/pipes.html

AngularJS display first element in array

Using Laravel for my API and the error response is like this:
I set that as a scope called errors and do a ng repeat to show them:
<ul ng-show="errors" class="list errors-list">
<li class="item" ng-repeat="error in errors">{{error}}</li>
</div>
However, this results in:
["The title field is required."]
Is there a 'best' way to just get the text and not the speech marks or brackets?
I know I can just search and replace them but always like to know if there is a best way to do something.
Just pull the first element
<ul ng-show="errors" class="list errors-list">
<li class="item" ng-repeat="error in errors">{{error[0]}}</li>
</div>
Quoting the documentation of AngularJS expressions, these are examples of valid expressions in Angular:
1+2
a+b
user.name
items[index] <--- This is what we're using for this answer

Trigger function on a certain element - ngrepeat - angularjs

Good morning,
I'm trying to change the limitTo filter on a certain list, my issue is:
when I click to the trigger who change the filter limit the filter changes on all ng-repeated categories.
my function inside the main controller
$scope.showMore = function(limit) {
if($scope.limitItems === $scope.itemsPerList) {
$scope.limitItems = limit;
$scope.switchFilterText = 'less';
} else {
$scope.switchFilterText = 'more';
$scope.limitItems = $scope.itemsPerList;
}
}
my scenario (I rewrote it in a simplified version)
<li ng-repeat="item in category.items | limitTo: limitItems ">
{{item.title}}
</li>
<li ng-if="limitItems < (category.items.length)">
<a ng-click="showMore(category.items.length)" >Show {{ switchFilterText }}</a>
</li>
Could you explain me what's wrong with me?
I searched how to select a single element to apply the function but I didn't find anything useful
Update:
I found the way to solve my issue in this way:
No functions inside the controller are involved to make this functionality works properly:
<li ng-repeat="category in maincategories" ng-init="limitItems = maxItemsPerList">
{{category.title}}
<ul>
<li ng-repeat="item in category.items | limitTo: limitItems "> {{item.title}}
</li>
</ul>
<a ng-click="limitItems = category.items.length" href>
<b ng-if="category.items.length > maxItemsPerList && limitItems != category.items.length "> Show more </b>
</a>
I'm not really convinced about Angular (I used it in my past and I was impressed by the performance but now I can see logics senseless):
What I learned:
ng-if and ng-click cannot be used in the same content because ng-if creates new scopes so if you put ng-if on top of the "show more" link it will break the code
ng-init cannot be used in the same element of the ng-repeat otherwise the var initialised will not be available inside the ng-repeat block
I think there is another way to do that, maybe more clean but in this specific case I can't do a lot.
ng-if and ng-click cannot be used in the same content because ng-if
creates new scopes so if you put ng-if on top of the "show more" link
it will break the code
Yes, ng-if creates a new scope, but it is possible to mix ng-if and ng-click (and most other directives). To do that, you'll be safer if you always write to atributes of another object instead of a simple variable. It is plain JavaScript prototypal inheritance in play.
<li ... ng-init="category.limitItems = maxItemsPerList">
ng-init cannot be used in the same element of the ng-repeat otherwise
the var initialised will not be available inside the ng-repeat block
True, in the sense that variables are created in the local scope. But again, refer to an object.
I think there is another way to do that, maybe more clean but in this
specific case I can't do a lot.
You don't need to do a lot, it is quite simple to do it right actually.
Some advices:
Use ng-init with care. I know it will tempt us but always try to put logic inside controllers and services;
Avoid assignments inside templates;
Learn how to use controllerAs syntax. It gives you an object to write your models to (the controller), so solves most problems related to scope inheritance;
Do not inject $scope, put your view models inside controllers.
Full code goes like this:
<li ng-repeat="category in maincategories" ng-init="category.limitItems = maxItemsPerList">
{{category.title}}
<ul>
<li ng-repeat="item in category.items | limitTo: category.limitItems "> {{item.title}}
</li>
</ul>
<a ng-if="category.items.length > maxItemsPerList && category.limitItems != category.items.length" ng-click="category.limitItems = category.items.length" href>
<b> Show more </b>
</a>

append data from handlebars value

i'm using emberjs with handlebars and i have an issue.
The idea is append a value into the element, the result will show something like that:
<li data-obj="CASH_IN_BANK">CASH_IN_BANK</li>
i'm trying that:
<li data-obj="{{row.value}}">{{row.value}}</li>
but is not working the result out the taks is fine but the data-obj shows the handlebar script tags
<li data-obj="<script id='metamorph-9-start' type='text/x-placeholder'></script>TAG_CASH_IN_BANK<script id='metamorph-9-end' type='text/x-placeholder'></script>" >
Any Suggestions?
You need to use `{{bind-attr attribute=value}}. See: http://emberjs.com/guides/templates/binding-element-attributes/
in your case it would be...
<li {{bind-attr data-obj=row.value}}">{{row.value}}</li>

Categories

Resources