mmenu is not initializated under angularjs - angularjs

I am developing a mobile application with left and right drawer, using mmenu (http://mmenu.frebsite.nl/) it is working fine till I've decided to populate items of the right menu on the fly. My app is based on angularjs and all directives of angularjs in body are working fine except all directives inside <nav id="menu-right">somehow, angularjs directives inside the menu definitions are not executed. I am not sure if it is something related with the order of executing javascript. Any help will be really appreciated. Thank you !!
UPDATED (07-April)
An example in jsfiddle http://jsfiddle.net/jmhostalet/wcK8L/
"My controller says" is working in the body but not in the mmenu, in body prints "Hello" but in mmenu prints nothing

The problems you were running into were:
First off the was not included in the declaration
You are changing the DOM without angular knowing about it therefor it does not have a chance to compile the braces {{myCtrlVar}}
It seems like extra work to create a directive but in the long run will allow you to reuse your code more. Also if you are like me and have bad javascript habits; it is nicer to use a framework to keep things straight.
My solution the in the plunker below shows "one way" to do what you are asking. It would be interesting to port the entire MMenu code over to an angular module in order to have more parameters and control.
(Never heard of MMenu, but seems like a cool project -- I will look more into it).
Plunker
(sorry I am inept at using fiddler)

Your fiddle doesn't have controller initialization on #menu-right but on his sibling element and therefore {{myCtrlVar}} expression can't access controllers scope objects.

Related

Making a directive load before ngController

I am trying to get experience with angular by making an app (for my own use) and I ran into an issue.
I decided to try to implement lazy loading (like in the "Complex" part of the answer to this question ) and had that working with my own additions to it.
I wanted to make components more self-contained though and decided to try to make a directive to load any javascript dependencies for me.
This left me with the following template html
<div dependencies="app/components/home/controller.js" ng-controller="HomeCtrl as home">
This is the home page.<br />
{{home.test}}
</div>
When I try to load this page I see the following error
Argument 'HomeCtrl' is not a function, got undefined
If I remove the ng-controller directive then my directive works fine and controller.js is loaded.
Based on the source for ngController I thought that setting the priority for my directive higher than 500 would work but it didnt seem to help.
I also tried moving my directives contents from link to compile.pre. It didnt help either, my directives compile runs before the error but compile.pre does not.
Is there any way to make my directive load/run first, before ngController?

What is the best way to debug angular code?

I'm a newbie in the Angular space. I've been having trouble debugging my code. Any methods proven more effective in debugging Angular?
open the developer console in the chrome browser, this allows you to:
set breakpoints and see whats going on in your code
use the console in the developer tools while you are waiting in breakpoints to execute some code or check the contents of variables
use the "select element" tool to select any HTML element, then in the console type "$scope" to see what's on the $scope of this element.
general tipps:
use some console.log statment like "running ControllerXYZ now" so you see, when your controllers are executed or when you are transitioning between states.
When using ui-router I find it extremly important to add a console.log statement into $stateChangeStart, $stateChangeSuccess and $stateChangeError event handlers, that shows you when you transition between states or when errors happen on state transitions, without that I am blind...
adding some {{anImportantVariable | json}} into html often is enough to debug stuff.
and the most important: if everything looks ok, and it still does not work, the problem is in 99%:
either a scoping issue (see here: Why do I need $parent to enable the function in ng-click when using ion-scroll?)
or a spelling mistake and a directive is not found (often because of the CamelCase in JS to dash-case in HTML: e.g. ngShow directive in JS is ng-show in HTML, and isOpenattribute in JS is is-open in HTML)
When it comes to inspecting the state: even though I always (irony) write unit tests for each and every conditional in my code (so I normally don't need to debug stuff) this is so far my favourite technique:
<pre ng-show='mymodel.debugPlz'>{{ mymodel.something | json }}</pre>
Simple example : fiddle
Chrome DevTools usually get the job done pretty well. You can insert a debugger; statement anywhere in the code and if Chrome DevTools are open, the code will stop there and you can further add breakpoint and traverse lines one by one. Other than that, there are a few extensions you can use by just searching for Angular in the Chrome Webstore. These usually help with inspecting $scope
what about using AngularJS Batarang chrome extention
it gives you a nice overview of the current scope within the selected element
as you see in the screenshot there is a new scope tab

Unit Testing the view of an Angular-UI modal

I've recently learned a lot about testing controllers w/ modals, modal controllers and directives. Almost everything in my app that can be tested, is being tested and it's all rainbows and kittens.
My latest (seemingly impossible) problem is that the modal I'm testing has a sort of "wizard" UI, where the user progresses through each step to create something to submit when the modal is closed. I'd like to test that the UI is reacting accordingly.
For example, in the modal controller, when $scope.cloneType is false, I'd like to make sure that my div#cloneMenu is actually showing (or hidden when cloneType has been set).
In a directive, I can do something like this:
$el.isolateScope().cloneType = null;
$scope.$digest();
expect($el.find('#cloneMenu').hasClass('ng-hide')).toBe(false);
$el.isolateScope().cloneType = 'basic';
$scope.$digest();
expect($el.find('#cloneMenu').hasClass('ng-hide')).toBe(true);
but I don't have $el (or anything like it) available in the modal controller (that I know of). I tried using $document.find() but that didn't work. I'm suspecting that $compile comes in to play at some point, but don't know where.
So, aside from just making the body of my modal a directive and unit testing that, is there any way of testing the DOM in the view of an AngularUI modal dialog? Any code samples or links to info that can help would be appreciated.
I'm using Angular 1.2.9 and Jasmine 2.0 and I've included jQuery so that I have a better find() method. (Being limited to tagName is lame when trying to test/traverse real DOM).
Thanks!
I'll provide an answer just so this question has the conclusion that I was after.
I think Sunil D. has it right with testing the views via an E2E test.
I was forcing myself to see the modal as a 'component' like a directive and so wanted to write tests in that way. I know it's not a directive, but it just felt more natural to test it that way because of how it works/looks/is similar to a directive (controller fn + template).
The other issue was that the controller for this thing is so small (because angular is so awesome) so there was only a couple of tests. I felt there should be more to it and wasn't getting the sense of completeness/accomplishment that I did from writing directive tests.
In the end, I'm just going to finish the tests for the modal controller and look into getting some E2E in the mix. That was next on my list anyway.

browser.executeScript doesn't see $scope

i am making a test with protractor for my angularjs app
and i came accross the following problem
what i want to do is :
browser.executeScript('$scope.$apply')
i want to do this so that my screen updates/renders so i can get the values on screen
only when i do this it says : $scope is not defined
if have also tried multiple javascript render ways who also failed ,but i am not sure if i have used the right methods for that...
does anybody has the same problem or know how to fix this?
Perhaps you should be using an ng-view directive in your container markup to render html snippets or partials within your index page. Take a look at what ng-view can do (http://docs.angularjs.org/api/ngRoute.directive:ngView) :-)

AngularJS Directive is not linking when using an input in the template to replace an input in the html with the type attribute specified

I'm having a really specific, strange issue.
We have to code our app to support IE8. We are wrapping the Angular-Bootstrap's Typeahead directive in a template to encapsulate a lookup widget with some extra functionality.
The issue we're having is that our directive template looks like this:
'<input ng-model="typeaheadValue" typeahead="xxx.code as formatXxx(xxx) for xxx in searchXxxs($viewValue)">'
Inside the link function in the directive we are simply calling replace: true and passing in some values to the scope.
This works beautifully in both IE8 and Chrome.
Now, the REALLY strange part is that, for IE8 only, if we say in the HTML in which we're using the directive:
<input type="text" search-directive>
It will not ever get into the link function. If i take the type="text" off everything works perfectly.
I created a simple JSFiddle to mimic what we're doing with a really basic test. Unfortunately for me the JSFiddle doesn't work in IE8 - but this is basically what we're doing. This can be found here: http://jsfiddle.net/lungsponge121/8xGuF/ (this is my first fiddle, not sure if it's editable or not)
After fighting with it for hours I've found the following: if i keep the html as (input type="text") and i replace the directive template input element with label or textarea it works fine, but when i use input it does not work at all. I also removed all of the typeahead code from the template and found that in IE8 it still doesn't work. The IE8 console did nothing for me and just gave me the standard illegal operation.undefined error.
I had somebody I work with help me debug my code and right now we're wondering if this is a bug. Has anybody else run into this - I'm thinking of submitting this to the Angular people as I can't find out how to get around this.
One thing jumped out at me: your directive is doing replace. The markup of the template you are replacing it with does not have the type="text", whereas the original markup does. I have noticed that replace does a sort of merge, and it may be getting confused when trying to merge or replace some HTML that has an attribute with a template that does not.
Interestingly, you don't really need to replace the original markup with a template at all. That is one use of directives, but not the most powerful in my opinion. Take "replace" off and remove the template entirely, if you're just trying to extend the typeahead anyway. In my own projects, for example, I might put several different directives attributes on a single element and they all add their own flavor of extra functionality to the existing element. All of them have a reference to the same $element, you just have to be careful that they don't conflict.
I wrote the rest of this before I looked at the fiddle first, sorry.
I'm on a chromebook so I can't test the IE8 thing, but if I recall IE is very picky about HTML attributes. Have you tried any of the following:
Alternate directive specification, as in data-search-directive
Make sure the directive has a property, as in search-directive="", even if you don't use it
Is the template cache really necessary? Have you tried this just by putting the template in a template property of the directive?
Is IE8 happy without "use strict"?
Have you seen the angular ui bootstrap alternative typeahead? At the very least, looking at what they did may give you ideas of how to do what you are trying to do.

Resources