angular / angular.js

AngularJS - HTML enhanced for web apps!
https://angularjs.org
MIT License
58.83k stars 27.51k forks source link

ngSwitch inside a template produces errors, "No controller: ngSwitch" #1900

Closed gwest7 closed 11 years ago

gwest7 commented 11 years ago

The live JSFiddle demo for ngView did not work for me. The view is not inserted into the DOM at all. None the less, I made the changes of the issue error I found and is viewable at http://jsfiddle.net/dqR2w/1/.

I will describe the problem below briefly.

Using the ngView directive I have a 'sub-template' as follows:

{{title}} ({{time}})<br/>
<p ng-repeat="item in tweets | filter:filterWhiteList | orderBy:created_at">
<ng-switch on="getType(item)">
    {{getType(item)}}
    <div ng-switch-when="tweet">{{item.from_user}}</div>
    <div ng-switch-when="text_ad">Text Ad</div>
    <div ng-switch-when="image_ad">Image Ad</div>
</ng-switch>
</p>

which produces to following in my browser:

KEYNOTE SPEECH TITLE (10:00-11:00)
tweet

tweet

text_ad

image_ad

Using version 1.0.3 I get an error for each ng-switch-when entry, "Argument '?' is required". Using version 1.0.4 I get "No controller: ngSwitch" for each ng-switch-when.

latentflip commented 11 years ago

@gary-buynary-co-za any chance of you putting your broken example up as a jsfiddle so we can look at it. Thanks.

gwest7 commented 11 years ago

Unfortunately jsFiddle does not handle inline templates well. The best I could do was base my example on the jdFiddle example of the ngView directive, but this example does not work to start off with.

Have you any advice?

latentflip commented 11 years ago

Maybe http://plnkr.co/ works better? Or can you stick your demo in a gist that we can download and see failing?

gwest7 commented 11 years ago

Managed to get Plunker to work. When selecting a chapter you will see the the types being displayed, but not the names. http://plnkr.co/edit/CVu8J1guaVH8h3r16j8r

The Gist when run in Chrome 24 and Firefox 18 give the same error. https://gist.github.com/4674002

jingman commented 11 years ago

Just wanted to add that I'm having the same issue, Error: No controller: ngSwitch, when trying to use an object's property as my ng-switch-on expression. Very simple example:

http://plnkr.co/edit/btQtgDqAd08VOVeHk2Sd?p=preview

jingman commented 11 years ago

...and that when using v1.1.1, the console error changes to Error: Argument '?' is required

gwest7 commented 11 years ago

We used ng-include as a work-around.

<ng-include src="switchFunction(value)"></ng-include>

The function contains the switch statement and returns a template path.

jingman commented 11 years ago

Ha, turns out I just had a typo - ng-switch-on="" instead of ng-switch on="". Fixing that cleared the errors and gave the expected result (in 1.1.1 at least).

Thanks for the tip on ng-include - that actually might solve another issue I'm having.

gwest7 commented 11 years ago

That is weird. The code in the example above was taken from the example in the documentation which has a space ng-switch on="". From what I can tell both should have worked.

Anyway, I did try the alternative in my Plunker example but still the same error.

Thanks for contributing.

jdsninja commented 11 years ago

@gary-buynary-co-za Any luck? I have the same problem. I don't want to but I may need to use ng-include.

wesleyhales commented 11 years ago

Huh, this (http://plnkr.co/edit/CVu8J1guaVH8h3r16j8r) works if you change your paragraph element to a div :)

Are there only certain HTML elements that allow ng-repeat, etc...?

gwest7 commented 11 years ago

That is interesting. Firstly it was probably bad practice from my part to have div tags inside a p...

I am no longer able to test with our original project as the code has changed completely. At the moment the section is a repeat of li tags, but this works as well.

Thanks for your input. I would like to the wait for someone official to comment on your question before I close this.

hairgamiMaster commented 11 years ago

Just confirming this issue in 1.0.5. Ng-switch within a templated View creates

Error: No controller: ngSwitch at Error () at h (https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js:41:96) at j (https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js:43:176) at e (https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js:38:331) at j (https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js:43:97)

gwest7 commented 11 years ago

Are you using ngSwitch inside ngRepeat?

gwest7 commented 11 years ago

I managed to get it working when I changed the tag my repeat was on from 'p' to 'div'. Hoping something simular works for you. Let me know.


From: robertborowiec [notifications@github.com] Sent: 10 April 2013 05:13 PM To: angular/angular.js Cc: Gareth Peter West Subject: Re: [angular.js] ngSwitch inside a template produces errors, "No controller: ngSwitch" (#1900)

@gary-buynary-co-zahttps://github.com/gary-buynary-co-za I am using a ngSwitch inside of an ngRepeat and it's not working for me (I got the problem after rearranging how my scripts load in require.js, didn't have it earlier, which is weird). How come? Shouldn't I?

— Reply to this email directly or view it on GitHubhttps://github.com/angular/angular.js/issues/1900#issuecomment-16180538.

hairgamiMaster commented 11 years ago

I coded around it somehow- can't remember where it was at this moment. That project has shipped and I'm on to the next one. Thanks for the tip!

davedx commented 11 years ago

I'm having a similar issue. In my case, the switch works with only one ng-switch-when, then adding subsequent ones gives me errors like this:

Error: No controller: ngSwitch at Error () at h (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js:41:398) at j (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js:43:477) at e (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js:39:116) at j (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js:43:398) at e (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js:39:248) at j (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js:43:398) at e (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js:39:248) at http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js:38:312 at

And:

Error: No controller: ngSwitch at Error () at h (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js:41:398) at j (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js:43:477) at e (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js:39:116) at j (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js:43:398) at e (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js:39:248) at j (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js:43:398) at e (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js:39:248) at http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js:38:312 at

At first I thought it was because I had my ng-switch-when inside tbody tags and I know browsers sometimes try to be clever with those, but then I changed it to divs and I'm still getting the issue. A bit higher in my HTML page I'm doing almost exactly the same thing and it's working there. Very difficult to tell what's causing it.

davedx commented 11 years ago

I figured out the problem: it was invalid HTML (i.e. I had tags inside other tags that shouldn't be there). In my case, I had multiple tbodys instead a table tag with trs and tds in each tbody. Apparently that's not valid HTML, so Angular was choking on it somehow.

codepic commented 11 years ago

If anyone reading this have a similar issue in IE8, try changing <ng-switch /> to <ng:switch /> and see if it works. Don't forget to apply the rest of the IE requirements described in the docs ;)

royts commented 11 years ago

helped me (had a typo too - 'ng-switch-on' instead of 'ng-switch on'

rod-glover commented 11 years ago

@codepic - Thank you, that saved me time, hassle, and inelegant code. Do you have any explanation at hand for why this is so? If you do, it might help some of us see deeper into the Angular / IE8 scenario.

rod-glover commented 11 years ago

@davedx - Multiple tbody elements inside a table is valid HTML in newer browsers. It was probably your (older) browser that was hiccuping, not Angular.

codepic commented 11 years ago

@rod-glover Only reason I can think of is that the document.createElement('ng-switch); is missing from the IE hacks as it's not included in the IE hacks here: http://docs.angularjs.org/#!/guide/ie

However the xmlns:ng is present in the document which makes the ng:switch work.

I haven't tested this theory and cannot currently do it on mobile, so if anyone could?

petebacondarwin commented 11 years ago

Remember that AngularJS only get access to the DOM as generated by the browser. So if you have dodgy HTML, the browser may choose to do funny things with it before it gets to AngularJS. For instance most browsers will convert this:

<p>One
  <div>Two</div>
  Three
</p>

to

<p>One</p>
<div>Two</div>
Three
<p></p>

You can see here that the div is no longer a child of the p.

Always check the validity of your HTML.

wobo-abhishek-zz commented 11 years ago

I had a similar same issue because of invalid HTML. A span tag was closing which had never been opened.