AngularJS: Uncaught Error: [$injector:modulerr] Failed to instantiate module? - angularjs

I am new to AngularJS and working my way through some documents and tutorials to learn. My question is in reference to Egghead's video series, this video in particular, demonstrating how to put together a basic search filter. I wanted to use this in a real app I'm building for a friend with a small candle-making business but when I modified it to be her candles rather than the Avengers cast (as demo'd in the video) I got this error:
Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to:
Error: [$injector:nomod] Module 'myApp' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify ...
I copied a redacted (only 3 cast members in the array) version of EXACTLY what is in the video demo into a jsfiddle and discovered it still yields the same error. (For reference, the Egghead demo is here: http://www.thinkster.io/angularjs/ET1iee6rnm/angularjs-ngfilter). I've read at least a half dozen similar questions on this site so far and tried every solution offered, but none of them get rid of this error or cause the Avengers search -- which works fine in the video demo -- to actually function properly.
HTML:
<div ng-app="myApp">
<div ng-controller="AvengersCtrl">
<input type="text" ng-model="search.$" />
<table>
<tr ng-repeat="actor in avengers.cast | filter:search">
<td>{{actor.name}}</td>
<td>{{actor.character}}</td>
</tr>
</table>
</div>
</div>
Javascript:
var myApp = angular.module('myApp', []);
myApp.factory('Avengers', function () {
var Avengers = {};
Avengers.cast = [
{
name: "Robert Downey Jr.",
character: "Tony Stark / Iron Man"
},
{
name: "Chris Evans",
character: "Steve Rogers / Captain America"
},
{
name: "Mark Buffalo",
character: "Bruce Banner / The Hulk"
}
];
return Avengers;
})
function AvengersCtrl($scope, Avengers) {
$scope.avengers = Avengers;
}
Simply put, can someone offer a solution that will work and get rid of this error, as well as explain in simple English (not Ph.D. level "Angular Obscurese") what causes it (in a nutshell) and what needs to be done to avoid it?
Edit: Apologies, but the jsfiddle link referenced above from the tutorial is no longer active. I have removed the broken link. The tutorial mentioned is still available for viewing.

Try using No Wrap - In Head or No wrap - in body in your fiddle:
Working fiddle: http://jsfiddle.net/Q5hd6/
Explanation:
Angular begins compiling the DOM when the DOM is fully loaded. You register your code to run onLoad (onload option in fiddle) => it's too late to register your myApp module because angular begins compiling the DOM and angular sees that there is no module named myApp and throws an exception.
By using No Wrap - In Head, your code looks like this:
<head>
<script type='text/javascript' src='//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js'></script>
<script type='text/javascript'>
//Your script.
</script>
</head>
Your script has a chance to run before angular begins compiling the DOM and myApp module is already created when angular starts compiling the DOM.

You have to play with JSFiddle loading option :
set it to "No wrap - in body" instead of "onload"
Working fiddle : http://jsfiddle.net/zQv9n/1/

For people having the same error with a similar code:
$(function(){
var app = angular.module("myApp", []);
app.controller('myController', function(){
});
});
Removing the $(function(){ ... }); solved the error.

For people who find this old posting on the web by searching for the error message, there is another possible cause of the problem.
You could just have a typo in your call to the script, even if you have already done the things described in the other excellent answer. So check to make sure you can used the right spelling in your script tags.

it turns out that I got this error because my requested module is not bundled in the minification prosses due to path misspelling
so make sure that your module exists in minified js file (do search for a word within it to be sure)

I had to change the js file, so to include "function()" at the beginning of it, and also "()" at the end line. That solved the problem

I know its know a 9 year old question, I was having this same error, I tried to put a js file containing AngularJS code in a directory where I also had the following files
I tried several things with no success until I just made a simple test to move outside that directory, isolating the file and that worked, I still don't know the reason. Hope this helps to someone

Related

Can i access the ng-app value in a protractor test?

I simplified the code i need to test to this:
<html ng-app="home" ng-strict-di=""><head>....
And i am running some protractor tests, i want to access the value of ng-app so i can compare and see which app is running in each page.
I have tried
var appName = element(by.xpath('/html/#ng-app'))
but it is not returning a usable promise or text i can compare with
appName.getText().then(function(name) {
expect(name).toBe('home')
});
But protractor complains:
InvalidSelectorError: invalid selector: The result of the xpath expression "/html/#ng-app" is: [object Attr]. It should be an element.
So i'm a bit baffled as how can i access my angular app name from protractor to test for app running independently of localization of labels.
Any insight into this enigma?
And it seems like magically, when you order your thoughts to formulate the question, the answer comes to you.
the trick is to get the html as element
var appNameHtml = element(by.xpath('/html'))
and then, in the test, get the ng-app attribute and use it:
appNameHtml.getAttribute('ng-app').then(function(value) {
expect(value).toBe('home');
});
And bingo, you can extract the app name.
Maybe this is a very basic question, but it was driving me insane :)
your answer will suffice I guess in this case. But just wanted to highlight a more generic approach in case ng-app may reside not only on html element.
var elementWithNgApp = element(by.css('*[ng-app]'))
And then wanted to add one more thing. You need not resolve the promise of getAttribute to do an expect on its value. Jasmine resolves the promise for you. You can have something like this
expect(elementWithNgApp.getAttribute('ng-app')).toBe('home');

angular intro.js not available

I have been trying to use angular intro js in my mockup angular js project the modal that asks whether the user needs to go through the tutorial is visible, However when I click the ok button that invokes the callMe method , an error is printed in the console stating,
message:"Intro.js is not available. Make sure it is properly loaded."
name:"Introjs not available."
Could anyone suggest where I am going wrong?
Make sure you have refered the angular-intro library and also injected as a dependency.
Reference:
<script src="intro.min.js"></script>
<script src="angular-intro.js"></script>
<script src="app.js"></script>
Module:
var app = angular.module('myApp', ['angular-intro']);
DEMO
Just to add to Sajeetharan's comment: It turns out that the order of dependency MATTERS. You must include the intro.js first, then angular-intro.js, then the main app.js.
Otherwise, you might get
Intro.js is not available. Make sure it is properly loaded." name:"Introjs not available.

Which method is good to use for laravel 5 and angularjs tag conflict?

I had print value issue in laravel view, i was trying to print $scope value inside laravel blade. I searched about and find two kind of solution.
1- Change angularjs print tag
By this method i can change angularjs print tag.
var app = angular.module('app', []);
app.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
});
app.controller('app', function ($scope, $http) {
$scope.text_print = 'this is text';
});
Now in blade i can print like <% text_print %>
2- Add # for printing angularjs $scope value
I found an up-voted answer in which #Paul A.T. Wilson says that
The easiest way to do this is to simply use # in front of your Angular code
Example #{{text_print}}
Both are working for me, actually i want to make a plugin, so which method should i use? because i'm not sure the second one is compatible with laravel old version. I want my plugin compatible with all version of laravel.
Can anyone guide me about this, i would like to appreciate. Thank You
Changing either interpolation strings for Blade or angular is the best option if you want your plugin to work with older versions of Laravel.
For angularJs you already know how to do it from here.
For Blade, inside your Laravel app's AppServiceProvider.php file add the following code in the boot function:
public function boot() {
Blade::setRawTags("[[", "]]");
// for variables and Blade
Blade::setContentTags('<%', '%>');
// for escaped data
Blade::setEscapedContentTags('<%%', '%%>');
}
Note: In my opinion it's easier to change the interpolation tags for angular as changing the interpolation tags for blade requires you to clear out the storage/framework/views folder.
Apparently there's another way to do this, but I'm not sure if it will work in older versions:
#verbatim
<div>
{{ variableOne }}
{{ variableTwo }}
</div>
#endverbatim
The verbatim annotation indicates that the section is as-is, ie: Blade will leave it out.

dijit.byId("").is not defined in Worklight works with Angularjs

I make a project in worklight used dojo mobile 1.8.1 and angularjs 1.0.1,but i got a strange problem.
Here is my html part:
<div data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props="selected:true" id="id1" ></div>
<div class="full" data-dojo-type="dojox.mobile.View" id="id2"></div>
and my JavaScript part:
require([
"dojo", "dijit/_base/manager","dojo/parser", "dijit/registry",
], function(dojo) {
dojo.ready(function() {
// dijit.byId("id1").performTransition("id2"); //////////place I
});
});
var angularApp = angular.module('app', [])
.run(['$rootScope','$templateCache','$route',
function($rootScope,$templateCache,$route) {
dijit.byId("id1").performTransition("id2");////////place II
}]);
The problem is at place I, it works well, but when I put "dijit.byId("id1")" at place II, it shows:
dijit.byId("").is not defined
The ready function is executed after dojo parsed your document & constructed the widgets you try to get using dijit.byId.
The second part is not placed within the ready function, so dojo can't find your elements yet !
Solution: Access your elements in the ready function OR do not declare them declaratively (like you did, using html code...) !
Lucian
The dojo.ready() function registers an event-handler function (callback) which will be fired after the DOM got completely parsed.
This comes in very handy if you want to be sure that every html element got rerendered as dojo-widget before you perform operations on them.
So, in your example, Code II will be executed before the dijit.byId() function has been made available by loading the necessary modules (dijit/registry, ...). Code II would only work after the dom-ready event got fired and your "dojo.ready()" function did load the required modules.
You should definately invest 5 minutes in reading what dojo.ready() is about:
http://dojotoolkit.org/reference-guide/1.8/dojo/ready.html
Sidenote:
You shouldn't use dijit.byId() any more in Dojo 1.8.1. Try using dijit.registry.byId() (you have to require the dijit/registry module).
http://dojotoolkit.org/reference-guide/1.8/dijit/registry.html#dijit-registry-byid

jQuery 1.3.2 conflict

I am using Jquery 1.3.2 for a script that needs it to run in IE 7/8.
The following code I've made to modify tabSlideOUt v1.3
By William Paoli: http://wpaoli.building58.com is causing a conflict and throwing an "Invalid Argument" error in jquery.
<script type="text/javascript">
$(document).ready(function() {
$("div#slidetab_1.slide-out-div a.handle").click(function () {
$("div#slidetab_2.slide-out-div").toggleClass("slide-height", 250) ;
});
$("div#slidetab_2.slide-out-div a.handle").click(function () {
$("div#slidetab_2.slide-out-div.tab2.slide-height").toggleClass("slide-height");
});
});
</script>
It seems that the toggleClass function is causing the error. Does anyone know of another way to code this so I don't have to use toggle?
I'm sorry it seems so vague but I was having trouble posting an example on JS Fiddle.
All I need is an alternative method for toggleClass
Thanks in advance
Cheers
The problem is that you pass 250 as second argument... what is it supposed to do in your code?
From the documentation:
switch A Boolean (not just truthy/falsy) value to determine whether the class should be added or removed.
It seems to have no purpose so I suggest to remove it.
Update: After having a look at the jQuery source code, passing 250 should not throw that error. Nevertheless I suggest to remove it and test it. If it does not work, you have to provide more information (where exactly the error is thrown, etc.).
Alternatively, you use this function to toggle the class:
function toggleClass($element, cls) {
$element[$element.hasClass(cls) ? 'removeClass' : 'addClass'](cls);
}

Resources