angular js error- 10 $digest() iterations reached. with angular ui Drop down - angularjs

I am using angular ui drop down element
<div class="dropdown" >
<a ng-click="getTypes();" dropdown-toggle> Add a Type</a>
<ul class="dropdown-menu">
<li ng-repeat="type in Types"><a><b>{{type.sType }}:</b><em>{{type.sDescription}}</em></a> </li>
</ul>
</div>
all that i do is call a web service and populate Types all works fine! But when i add the above code in my htm the div below it starts throwing the exception of max digest reached.
the div below the drop down code(as written above) simply consists of few editable segments with icons and their visibility is controlled by ng-show and ng-hide when the use click a button
say on click of 1st segment i set a variable to true by using ng-click and depending on this variable i show or hide segments by using ng-show and ng-hide
so my doubt is that without the drop down code written above my ng-show and ng-hide work completely fine but the moment i try to use the drop down directive of angular ui i start getting this exception when i click on the buttons . please help.
Edit below is the code which follows basically user clicks on icons to reorder the elements that are appearing in the ng-repeat list and from the drop down which is above the user can add elements to this list
<ul class="repeatList text-center">
<li ng-repeat="widgets in leftWidgets" widget widgets="widgets"
class="wArea">
<a href="" class="icon-remove-circle pull-right" ng-show="editMode" ng-click="deleteWidget(leftWidgets);"
title="Delete Widget">
</a>
<a href="" class="icon-chevron-up slideUpIcon" ng-click="shiftUp(widgets,leftWidgets);"
ng-show="editMode">
</a >
<a href="" class="icon-chevron-down slideDownIcon" ng-click="shiftDown(widgets,leftWidgets);"
ng-show="editMode">
</a>
</li>
</ul>

kept doing hit and trial and found that using empty anchor tags was causing the problem. i.e. i had attached ng-click events to
text //empty href
the moment i changed them to span all worked fine! dont know why the empty "a" tags caused the problem but it will be great if any one can shed some light on the reasons for the above run time angular js exception. the link below is a useful
How to Troubleshoot Angular "10 $digest() iterations reached" Error
thanks!

Related

Angular-Elements are not refreshing after aborted drag&drop

I have the following angular-List (reduced the content to make it better readable):
<div ng-repeat="element in bigBlock.Elements track by $index"
class="singleBlockElement"
ng-drop="dragSource=='Block'"
ng-drop-success="To($index, $data, bigBlock)">
<div class="bbRange"> </div>
<i class="fa {{GetImage(element)}}" />
<div ng-drag="element.ElementType!=='placeholder'"
ng-drag-data="element"
ng-drag-start="Start()"
ng-drag-success="From(element,bigBlock, $index, bigBlock.$index)"
ng-drag-stop="Stop(element, bigBlock, $index, bigBlock.$index)"
class="cutOff">
{{element.Title}}
</div>
<div class="edit ng-show="GetLinkText(element, true)">
<span class="isvisible">
<i title="{{element.Present?'Präsentieren':'Nicht präsentieren'}}" class="fa fa-{{element.Present?'eye':'eye-slash'}}"></i>
</span>
{{GetLinkText(element,true)}}
</div>
</div>
This is how it looks like:
This is while dragging:
And this is how it looks like when I simply don't drop like described below:
I can now (successfully) drag & drop the two elements ("Welcome" and "Go Away") inside that block changing the order of these two.
But if I abort the drag/drop. e.g. Dragging "Welcome" and not moving it downwards or moving it to an area where I cannot drop (outside the block) the text "Welcome" disappears.
There are no errors. The drop is just not happing (as expected), but Angular seems to be unable to redisplay the text of that element. ({{element.Title}})
I event tried forcing a refresh using $apply(), but this did not change a thing (not creating an error either).
However, if I do ANYTHING on the page like clicking on an edit-button or anything else that causes an event, the date is correctly shown again.
So it looks like a refresh issue for me.
I am using ngDraggable for this (https://github.com/fatlinesofcode/ngDraggable)
(Update: Analyzing the page source in Developer Console of Chrome the text still seems to be there and even "should" be visible (display:block), so this might be more of a browser-issue (chrome) than an angular-issue)
This seems to be a pure Browser/CSS-Issue and not an Angular-Issue. I solved this by forcing the browser to refresh the parent container:
$('.mm-Right')[0].style.display = 'none';
$('.mm-Right')[0].offsetHeight;
$('.mm-Right')[0].style.display = 'block';
where my structure is
<div class='mm-Right'>
<div class='singleBlockElement>[..]</div>
<div class='singleBlockElement>[..]</div>
<div class='singleBlockElement>[..]</div>
</div>
That did solve the problem but looks like cheating for me. I would prefer that this bug not even appears instead of hiding the symptoms. So I am happy to accept any better answer for that problem.

Evaluate AngularJS expression within Material Design Lite's mdl-menu

I am building a tiny single-page-application using Angular for the functionality and mdl for the design. I wanted to have a dropdown select box and since mdl doesn't provide this out of the box I built one using mdl-menu. The problem is now that Angular seems to have troubles evaluating expressions I put inside this menu, maybe because the menu is only opened when you click the button? I tried using expressions within the list items and this gives the expression output but also the original expression, which I obviously don't want. I also tried to ng-repeat the list items and then they just don't show up.
<button id="demo-menu-lower-left"
class="mdl-button mdl-js-button mdl-button--icon">
<i class="material-icons">more_vert</i>
</button>
<ul class="mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect"
for="demo-menu-lower-left">
<li class="mdl-menu__item">{{5+5}}</li>
<li class="mdl-menu__item mdl-menu__item--full-bleed-divider">Another Action</li>
<li disabled class="mdl-menu__item">Disabled Action</li>
<li class="mdl-menu__item">Yet Another Action</li>
</ul>
Result pic (Look at the evaluation in the top left, but the original expression is the actual "clickable" action)
Thx in advance!
MDL's javascript (denoted by the mdl-js CSS classes) will probably fool around with the HTML before Angular can do anything, eventually creating HTML that gives strange results when 'parsed' by Angular. It would be best to ensure your HTML gets processed in a strict order: Angular first, MDL second.
If you need to work with the HTML after the initial loading and rendering of the page, it would help to inspect the HTML in the browser instead of relying on the source HTML. Any javascript code (including Angular) will have to work with this and not the HTML represented by the source.

Spring Security vS AngularJS -> Problems when using sec:authorize tag

I am creating a dynamic menu, all info of the menu I am getting from mysql database.
In my 'menu' database, there's a column called "role_access", where I can manipulate the roles. My intention is to fill this column in the database for each rule I have, then using the code below I could show/hide the menus depending if the client is USER or ADMIN.
<sec:authorize access="hasRole('{{roleAccess}}')">
<li class="menu-dropdown classic-menu-dropdown "><a
data-hover="megamenu-dropdown" data-close-others="true"
data-toggle="dropdown" href="javascript:;"> <span
ng-bind="menu.nome"></span>
</a>
<ul class="dropdown-menu pull-left">
<li ng-repeat="menu in menu.submenus"><span ng-bind="menu.nome"></span>
</li>
</ul></li>
</sec:authorize>
But, when loading the page, Spring Life's Cycle (loads everything before) is different from AngularJS (loads everything after page is loaded).
So, when using {{roleAcess}}, AngularJS is not loading my menu. If I force this roleAccess manually without the {{}}, it works.
Thanks in advance.

Popovers misplaced in some HTML elements

I am working in a project where I use jQuery (~2.1.1), Bootstrap (~3.3.1), AngularJS (~1.3.4), Angular-ui-bootstrap (~0.12.0), and some more libraries. I have a small problem which is related with the popover directive of the angular-bootstrap library. This little problem is that many of the popovers are misplaced, so probably I am forgetting about something.
From the documentation and even personal tests (Plunker Example Ex. using angular 1.3.4), the popover should look aligned to the center of the HTML element, and the arrow of it should touch the element, like this:
The problem is that in my application the popover gets misplaced somehow (In this case only vertically the offset is noticeable, so it's not touching the element), as you can see next:
Another example (which is the most noticeable) is with a dynamic generated list using ng-repat, as you can see in the next picture:
<div class="col-xs-6 col-sm-2 sidebar-offcanvas"
id="sidebar-left" role="navigation">
<div class="list-group shadow-bottom" id="sideMenuTitle">
<span class="list-group-item list-group-item
disabled offcanvas-title" style="text-align: center">
<strong>Metrics</strong>
</span>
<a popover="{{metrics_messages[$index]}}" popover-popup-delay="450" popover-trigger="mouseenter"
popover-placement="top" popover-animation="true" ng-repeat="m in metrics" ui-sref="{{m.sref}}"
class="list-group-item"
ng-click="selectMetric(m)" ng-class="{active: m.selected}">{{m.caption}}</a>
</div>
</div>
PS: I included ui.bootstrap to the "global" angular module, as they suggest Angular Bootstrap Site.
The problem was related to the version where this post was made, after that version they fixed this problem.

correct strategy to generate html dynamically with angular

I have a huge JSON object tree with two levels. First level has around 500 elements, and each element contains an average of 100 child elements.
I want to display the first level of the tree and I am doing it with a simple ng-repeat. When the user clicks on the element I want to display the child elements of that element. If I use a span ng-switch or a ng-show to show/hide child elements when the page first renders it freezes for around 10 seconds while generating all the HTML.
It doesn't sound like the right solution. There must be a different way of doing it, but I can't figure out. Anyone knows?
I have explained most in my comment, and here is a working plunker:
http://plunker.co/edit/RSZwfLlsCJ68MUkACbdp?p=preview
the new ng-if directive will do what you want
<h1>ng-if</h1> <h5>Click on the level to expand</h5>
<div class="well">
<ul class="nav nav-list" ng-repeat="(attr,element) in tree">
<li ng-click="expand=!expand" ng-class="{'active':expand}"><a>{{element.name}}</a></li>
<ul ng-if="expand" class="nav nav-list">
<li ng-repeat="item in element.items">{{item.name}}</li>
</ul>
</ul>
</div>
you can also do this in the "old-way" with ng-show using new ternary operator or its alternative expr && if_true || if_false
<h1>old-way</h1> <h5>Click on the level to expand</h5>
<small>use ternary operator or <pre>expand && element.items || []</pre></small>
<div class="well">
<ul class="nav nav-list" ng-repeat="(attr,element) in tree">
<li ng-click="expand=!expand" ng-class="{'active':expand}"><a>{{element.name}}</a></li>
<ul ng-show="expand" class="nav nav-list">
<li ng-repeat="item in (expand ? element.items : [])">{{item.name}}</li>
<!--<li ng-repeat="item in (expand && element.items || [])">{{item.name}}</li>-->
</ul>
</ul>
</div>
See this answer on ng-repeat performance. Essentially, it just takes a long time since Angular's ng-repeat, and basically all other directives, are set up to always look for updates in the whole JSON structure. So if you have lots of data and don't need live updates in the HTML view when changing the JSON, I wouldn't recommend using AngularJS. Generally, AngularJS performance also depends a lot on the browser and its JavaScript engine.
Alternatively, you could divide your JSON into subparts and then use pagination to display it.
I would recommend to fetch the data gradually from the server. Use server-side pagination and retrieve only the fields that you are going to display. Then, when a user clicks on one of the first level items, you can do another XHR to the server with the new data. I had similar requirements for a project and that solved the latency issue.
Regards,
Agustin.

Resources