Angular ng-repeat not being refreshed - angularjs

I have the following simple directory listing. I wish to upload a file and have the ng-repeat list update.
<h3>Directory Listing</h3>
<li ng-repeat="file in filearray track by file.id">
{{file.id}} {{file.filename}}
</li>
I have tried pushing a new item into the filearray array in my controller
$scope.filearray.push({id:max_id, filename: filename});
I have also tried to call the endpoint that provides the directory listing
I have tried with and without $scope.$apply, somehow the ng-repeat does not update (also tried with and without track by). Can someone shed some light on ng-repeat and why it does not dynamically update even on an $scope.$apply ?
EDIT : PROBLEM SOLVED
I had two calls in the main code to the controller ...
<div class="main" ng-controller="MainController">
<form ng-controller="MainController">
...

Related

AngularJS - Binding same scope to multiple copies of a form using ng-include

I have a simple search form which I have it included in two different pages using ng-include directive. I would like to bind them both to the same scope in such a way that when the user navigates between the pages, they'll keep seeing the same search data they've entered in either of the copies.
I have managed to implement an untidy solution using rootScope, but would like to know if this can be implemented in a proper, cleaner way?
I also used root scope slove it, my layout below:
<div id="page-header" ng-include="'views/layouts/header.html'"></div>
<div id="content">
<div ui-view="content" ng-cloak></div>
</div>
<div id="page-footer" ng-include="'views/layouts/footer.html'"></div>
<div id="toastElement">
<ul id="toastBox"></ul>
</div>
header.html bound HeaderController, the functions in HeaderController include search, login, logout, register and both working on $rootScope. Is it helpful?

ng-repeat triggers every time i reload my view

I'm creating a website with multiple tabs, and one of them is listing elements, it's the Product tab.
I've got a problem with "ng-repeat", I want to fill a HTML depending on a table of table in angular on the tab, it works fine on the first load, but if I go to another tab and then go again on the product tab, the "ng-repeat" repeats once more and it stacks with the first one.
Example:
Firstload: an apple and a strawberry are loaded fine.
Secondload: I now have apple strawberry and apple strawberry
And so on.
<slick dots="true" prev-arrow="null" next-arrow="null" init-onload="true" data="productsTab">
<div class="productsPage scrollBar" ng-repeat="tab in productsTab">
<div class="productsProduct" ng-repeat="product in tab">
<div class="productsProductTitle">{{product.name}}</div>
</div>
</div>
</slick>
I can also say that I load my data from a factory that I get in controller this way:
productsFactory.build().then(function(facto) {
$scope.productsTab = facto;
});
Hope you can help me!
I think your problem is that init-onload. I am not sure what it does, but if it triggers the call to the controller in some way, it also triggers the promise every time you go back to the tab. You can cache the results from the promise inside the service. Here's an article from this site on how to cache promises:
Caching a promise object in AngularJS service
Hope this will help.
Here is example how to handle multiple ng-repeats, I hope this will help you.
http://plnkr.co/edit/TfGMm1SgpRmgFSTuTuE0?p=preview
<script>
var app=angular.module('myapp',[])
app.controller('demo',function($scope){
$scope.products={
product:[{
name:'abc'
}]
}
})
</script>
</head>
<body ng-app="myapp" ng-controller="demo">
<div ng-repeat="product in products">
<div ng-repeat="p in product">
<span>{{p.name}}</span>
</div>
</div>
</body>
I noticed from the docs I found here https://github.com/vasyabigi/angular-slick that there are no parenthesis on on-init=true. Not sure if that matters.
When I have issues with arrays not resetting I use angular.copy() an empty list variable before loading to the scope. That way I know the array is empty before I add anything to it.

Self contained Angular Template is not setting variables correctly

I am trying to build a star ranking purely in an angular template file without using controllers, I have the following code which fails, I can build this using controllers (calling setRanking method ng-click) but I want to understand why the following code is not working. User should be able to click on a star and all the stars up to the selected star should be highlighted.
<div class="item" ng-init="user_rating = 0">
<i
ng-repeat="star in [1,2,3,4,5]"
ng-class="(star>user_rating) && 'ion-ios-star-outline' || 'ion-ios-star'"
ng-click="user_rating = star"></i>
<h3>Starts: {{user_rating}} </h3>
</div>
I think the issue is with the scope of the user_rating(as it is not getting updated).
As each ng-repeat creates the isolated scope, so the way you are updating user_rating is creating a local copy of user_rating associated to the local scope of each ng-repeat.
To fix it you can replace the code
ng-init="user_rating = 0"
with
ng-init="r={}; r.user_rating = 0;"
Also refer user_rating with r.user_rating wherever you are referring user_rating.
Also the correct way of using ng-class is what #Shailendra mentioned in his answer. Thanks!
You need to make changes in this code for 'ng-class' as like below-
<div class="item" ng-init="user_rating = 0">
<i
ng-repeat="star in [1,2,3,4,5]"
ng-class="star>user_rating? 'ion-ios-star-outline': 'ion-ios-star'"
ng-click="$parent.user_rating=star;"></i>
<h3>Starts: {{user_rating}} </h3>
</div>
I Hope this may help you..

AngularJS Animations ng-switch ng-repeat

I am trying to do what looks like a simple process: to display a list of items received from an HTTP request with animation.
First of all, here is my way of doing it ( I am open to any suggestions to do it in a better angular way ):
I define a scope variable state that I initialize to loading in my controller and that I change to loaded when I receive data from the HTTP request.
I initialize a scope variable items with the received data.
In my view, I use ng-switch for the states, and ng-repeat with the items.
I define an animation with css on ng-repeat.
Here is a plunkr ( with a $timeout instead of the request ).
I cannot understand why the animation does not work.
Any help will be appreciated. Thanks.
The reason it is happening is because your ng-when. The same thing happens with ng-if, but would work fine if you used ng-show.
The problem is that when your ng-when condition returns true, the ng-when first renders it's content in a detatched dom (so animations do not happen). This dom is then attached to the dom tree (this step is animated but you would have to put your animation class on the ng-when).
When using something like ng-show or ng-hide things work as expected because the dom is always attached (it is simply shown/hidden).
This might be considered either a bug or a limitation of ng-animate, you might want to post a github issue and see if the angular guys have any thoughts.
It seems to be a "feature" of angular that it won't add .ng-enter to repeat items inside ng-switch-when block. You can remove ng-switch-when="loaded" and it will work (You don't really need it as ng-repeat won't do anything if there is no items)
<div ng-switch="state">
<div ng-switch-when="loading">
<p>Please wait...</p>
</div>
<div >
<ul ng-repeat="item in items" class="animate-items">
<li>{{item}}</li>
</ul>
</div>
</div>
http://plnkr.co/edit/ocEj7BSQPSeIdnnfAOIE?p=preview

Iterating over a list and calling directives depending upon the item types , in angular js

I have a HTML file it iterates over a list of objects as shown and every object has a template( stored in the db) that it uses I get "List" from a web service :-
<ul>
<li ng-repeat="object in List" ng-include="object.TemplateName" > </li>
</ul>
Let object.TemplateName be "template1"
A sample template would have a specific directive with the attributes needed and few html tags as shown "template1":-
template1:-
<directive1 s-web-service-path="object.WebServicePath" >
<h1>any html content</h1>
</directive1>
my directive calls a web service to get the content to be displayed and has its own template... instead of putting directives in a template and including them cant I directly call my directive depending upon the different types of objects that i obtain in List
something like
for Object.Type="1" i call directive1 instead of template1
for Object.Type="2" i call directive2 instead of template2
ngIf or ngSwitch might be helpful here, with a few extra wrapping elements within the ngRepeat, in order to dynamically choose what to include based on Object.Type. Using ngSwitch:
<ul>
<li ng-repeat="object in List">
<div ng-switch="object.Type">
<div ng-switch-when="'1'">
<div ng-include="object.TemplateName"></div>
</div>
<div ng-switch-when="'2'">
<directive1 s-web-service-path="object.WebServicePath" >
<h1>any html content</h1>
</directive1>
</div>
</div>
</li>
</ul>
The above is not tested, so there could potentially be an error. You might also be able to cut down on some of DOM nesting level by including the ng-switch-when attributes on the directive1 / ng-include divs, but the way above makes the behaviour clear, and avoids any unexpected issues that might arise from having multiple directives work on the same element.

Resources