Directive not working in angularjs - angularjs

I am newbie to Angularjs. I am trying to create simple directive with the following code:
View:
<html>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<user-info></user-info>
</div>
</body>
</html>
Controller:
myapp = angular.module("myapp", []);
myapp.directive('userInfo', function() {
var directive = {};
directive.restrict = 'E'; /* restrict this directive to elements */
directive.template = "My first directive: ";
return directive;
});
I am following this Tutorial to learn directive
http://tutorials.jenkov.com/angularjs/custom-directives.html
I am getting error:
http://errors.angularjs.org/1.3.14/$injector/modulerr?p0=myApp&p1=Error%3A%20%5B%24injector%3Anomod%5D%20http%3A%2F%2Ferrors.angularjs.org%2F1.3.14%2F%24injector%2Fnomod%3Fp0%3DmyApp%0A%20%20%20%20at%20Error%20(native)%0A%20%20%20%20at%20http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.14%2Fangular.min.js%3A6%3A417%0A%20%20%20%20at%20http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.14%2Fangular.min.js%3A21%3A412%0A%20%20%20%20at%20a%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.14%2Fangular.min.js%3A21%3A53)%0A%20%20%20%20at%20w.bootstrap%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.14%2Fangular.min.js%3A21%3A296)%0A%20%20%20%20at%20http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.14%2Fangular.min.js%3A35%3A46%0A%20%20%20%20at%20s%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.14%2Fangular.min.js%3A7%3A302)%0A%20%20%20%20at%20g%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.14%2Fangular.min.js%3A34%3A399)%0A%20%20%20%20at%20ab%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.14%2Fangular.min.js%3A38%3A135)%0A%20%20%20%20at%20d%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.14%2Fangular.min.js%3A17%3A381
Here is my codepen link
http://codepen.io/anon/pen/NGNKxz

You have error in the name of your app :
myapp = angular.module("myApp", []); // not 'myapp'

Add Your Directive
You need to add the directive to your html like so
<script src="path/to/your/directive.js"></script>
or if your working from one module you will link to the main module. But please restructure your app like this it will keep code up to standard and clean.
I have a git hub repo where I am building an app in this structure here. Best of luck.
Note
You are using angular min. Min is great for production because its small and faster to load but your in development at the moment so use the full version so you can capture errors better with the browser console.

Looks like you did not declare the controller myCtrl. Your directive looks fine.
myapp.controller('myCtrl', function() {
});

Is it the current version of your html file ?
Because you might need to link your controller, between head tags, insert :
<script src="the js file which contains your controller"></script>
or
<script>Your controller</script>

Related

Angular is not defined error

I am trying to create a login page and I have the html looking how I want it so now I am trying to create a controller but for some reason the js controller isnt working with the html. here is the plunker. The {{name}} data bind should display world but it isnt. Here is the controller:
(function() {
"use strict";
var app = angular.module('plunker', []);
app.controller('LoginController', function($scope) {
$scope.name = 'World';
});
})();
http://plnkr.co/edit/mqc6ksw1xo7NMhj74Noa?p=preview
The issue is your angularjs link is not working , just replace with this,
<script data-require="angular.js#*" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular.min.js"></script>
Working code
You have the wrong link so it can't load angular, change
https://code.angularjs.org/2.0.0-alpha.31/angular.js
to
https://code.angularjs.org/2.0.0-alpha.31/angular2.js
note the extra '2' at the end

Angular Scope Directives

Angular Structural Question
I am new to angular.js and am just wondering how to go about performing a certain situation.
So basically, what I have got is a container:
<div ng-controller="ContainerController">
<container></container>
</div>
And the container controller and directives.
<script type="text/javascript" src="ContainerController.js"></script>
<script type="text/javascript" src="ContainerDirectives.js"></script>
Now the directives replaces the <container> tag with an example html: <example>{{ data }}</example>
Now within the scope of the ContainerController I have defined data as a string. (This is all example purposes). However when the directive accesses replaces it, it is unable to find the variable, due to scope.
The reason that this happens is because the ContainerDirective script's scope is not within the ContainerController scope. Meaning it is unable to access the variable.
Im just not sure on structure practices for these kinds of situations. Where do I put everything so the ContainerDirective can access the ContainerController scope.
I hope i have explained everything good enough
EDIT:
Test.js
(function(){
angular.module('test', []);
})();
TestController.js
(function(){
angular
.module('test')
.controller('TestController', [
'$scope',
TestController
]);
function TestController($scope) {
$scope.test = 'test';
}
})();
TestDirective.js
(function(){
angular.module('test').directive('test', function () {
return {
replace: true,
templateUrl: 'src/test/view/test.html',
link: function (scope, element, attrs) {
}
};
});
})();
test.html
<example>ClickMe</example>
index.html - body
<body ng-app="App" layout="row" ng-controller="TestController as page">
<test></test>
<script src="src/test/Test.js"></script>
<script src="src/test/TestController.js"></script>
<script src="src/test/TestDirective.js"></script>
<script type="text/javascript">
angular
.module('App', ['test']);
</script>
</body>
For reasons I have renamed certain variables and deleted a lot of data, but this is the core, and I am struggling to see anything wrong with this.
Error: [$interpolate:noconcat] Error while interpolating: abc/{{test}}
Strict Contextual Escaping disallows interpolations that concatenate multiple expressions when a trusted value is required.
So I figured out what was wrong in the end. Basically angular wont allow iframe of another location to be printed unless you first:
Give them the full url.
Then allow external url as a trusted website.
TO do this I had to basically add:
in the Test.js
angular.module('test', []).config(function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist($sceDelegateProvider.resourceUrlWhitelist().concat([
'http://www.test.com/**'
]));
});
This basically took my whitelist and concatinated the new url to it.
Then inside test.html:
<example><iframe ng-src={{src}}></iframe></example>

Angular JS Problemsss [duplicate]

I am writing a sample application using angularjs. i got an error mentioned below on chrome browser.
Error is
Error: [ng:areq] http://errors.angularjs.org/1.3.0-beta.17/ng/areq?p0=ContactController&p1=not%20a%20function%2C%20got%20undefined
Which renders as
Argument 'ContactController' is not a function, got undefined
Code
<!DOCTYPE html>
<html ng-app>
<head>
<script src="../angular.min.js"></script>
<script type="text/javascript">
function ContactController($scope) {
$scope.contacts = ["abcd#gmail.com", "abcd#yahoo.co.in"];
$scope.add = function() {
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
};
}
</script>
</head>
<body>
<h1> modules sample </h1>
<div ng-controller="ContactController">
Email:<input type="text" ng-model="newcontact">
<button ng-click="add()">Add</button>
<h2> Contacts </h2>
<ul>
<li ng-repeat="contact in contacts"> {{contact}} </li>
</ul>
</div>
</body>
</html>
With Angular 1.3+ you can no longer use global controller declaration on the global scope (Without explicit registration). You would need to register the controller using module.controller syntax.
Example:-
angular.module('app', [])
.controller('ContactController', ['$scope', function ContactController($scope) {
$scope.contacts = ["abcd#gmail.com", "abcd#yahoo.co.in"];
$scope.add = function() {
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
};
}]);
or
function ContactController($scope) {
$scope.contacts = ["abcd#gmail.com", "abcd#yahoo.co.in"];
$scope.add = function() {
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
};
}
ContactController.$inject = ['$scope'];
angular.module('app', []).controller('ContactController', ContactController);
It is a breaking change but it can be turned off to use globals by using allowGlobals.
Example:-
angular.module('app')
.config(['$controllerProvider', function($controllerProvider) {
$controllerProvider.allowGlobals();
}]);
Here is the comment from Angular source:-
check if a controller with given name is registered via $controllerProvider
check if evaluating the string on the current scope returns a constructor
if $controllerProvider#allowGlobals, check window[constructor] on the global window object (not recommended)
.....
expression = controllers.hasOwnProperty(constructor)
? controllers[constructor]
: getter(locals.$scope, constructor, true) ||
(globals ? getter($window, constructor, true) : undefined);
Some additional checks:-
Do Make sure to put the appname in ng-app directive on your angular root element (eg:- html) as well. Example:- ng-app="myApp"
If everything is fine and you are still getting the issue do remember to make sure you have the right file included in the scripts.
You have not defined the same module twice in different places which results in any entities defined previously on the same module to be cleared out, Example angular.module('app',[]).controller(.. and again in another place angular.module('app',[]).service(.. (with both the scripts included of course) can cause the previously registered controller on the module app to be cleared out with the second recreation of module.
I got this problem because I had wrapped a controller-definition file in a closure:
(function() {
...stuff...
});
But I had forgotten to actually invoke that closure to execute that definition code and actually tell Javascript my controller existed. I.e., the above needs to be:
(function() {
...stuff...
})();
Note the () at the end.
I am a beginner with Angular and I did the basic mistake of not including the app name in the angular root element. So, changing the code from
<html data-ng-app>
to
<html data-ng-app="myApp">
worked for me. #PSL, has covered this already in his answer above.
I had this error because I didn't understand the difference between angular.module('myApp', []) and angular.module('myApp').
This creates the module 'myApp' and overwrites any existing module named 'myApp':
angular.module('myApp', [])
This retrieves an existing module 'myApp':
angular.module('myApp')
I had been overwriting my module in another file, using the first call above which created another module instead of retrieving as I expected.
More detail here: https://docs.angularjs.org/guide/module
I just migrate to angular 1.3.3 and I found that If I had multiple controllers in different files when app is override and I lost first declared containers.
I don't know if is a good practise, but maybe can be helpful for another one.
var app = app;
if(!app) {
app = angular.module('web', ['ui.bootstrap']);
}
app.controller('SearchCtrl', SearchCtrl);
I had this problem when I accidentally redeclared myApp:
var myApp = angular.module('myApp',[...]);
myApp.controller('Controller1', ...);
var myApp = angular.module('myApp',[...]);
myApp.controller('Controller2', ...);
After the redeclare, Controller1 stops working and raises the OP error.
Really great advise, except that the SAME error CAN occur simply by missing the critical script include on your root page
example:
page: index.html
np-app="saleApp"
Missing
<script src="./ordersController.js"></script>
When a Route is told what controller and view to serve up:
.when('/orders/:customerId', {
controller: 'OrdersController',
templateUrl: 'views/orders.html'
})
So essential the undefined controller issue CAN occur in this accidental mistake of not even referencing the controller!
This error might also occur when you have a large project with many modules.
Make sure that the app (module) used in you angular file is the same that you use in your template, in this example "thisApp".
app.js
angular
.module('thisApp', [])
.controller('ContactController', ['$scope', function ContactController($scope) {
$scope.contacts = ["abcd#gmail.com", "abcd#yahoo.co.in"];
$scope.add = function() {
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
};
}]);
index.html
<html>
<body ng-app='thisApp' ng-controller='ContactController>
...
<script type="text/javascript" src="assets/js/angular.js"></script>
<script src="app.js"></script>
</body>
</html>
If all else fails and you are using Gulp or something similar...just rerun it!
I wasted 30mins quadruple checking everything when all it needed was a swift kick in the pants.
If you're using routes (high probability) and your config has a reference to a controller in a module that's not declared as dependency then initialisation might fail too.
E.g assuming you've configured ngRoute for your app, like
angular.module('yourModule',['ngRoute'])
.config(function($routeProvider, $httpProvider) { ... });
Be careful in the block that declares the routes,
.when('/resourcePath', {
templateUrl: 'resource.html',
controller: 'secondModuleController' //lives in secondModule
});
Declare secondModule as a dependency after 'ngRoute' should resolve the issue. I know I had this problem.
I was getting this error because I was using an older version of angular that wasn't compatible with my code.
These errors occurred, in my case, preceeded by syntax errors at list.find() fuction; 'find' method of a list not recognized by IE11, so has to replace by Filter method, which works for both IE11 and chrome.
refer https://github.com/flrs/visavail/issues/19
This error, in my case, preceded by syntax error at find method of a list in IE11. so replaced find method by filter method as suggested https://github.com/flrs/visavail/issues/19
then above controller not defined error resolved.
I got the same error while following an old tutorial with (not old enough) AngularJS 1.4.3. By far the simplest solution is to edit angular.js source from
function $ControllerProvider() {
var controllers = {},
globals = false;
to
function $ControllerProvider() {
var controllers = {},
globals = true;
and just follow the tutorial as-is, and the deprecated global functions just work as controllers.

How can I load dynamically my AngularJS application dependencies

Let's say, I have HTML like this
<html ng-app='CoreAngular_App'>
<script>
var CoreAngular_AppObj = angular.module('CoreAngular_App', ['importantModule1', 'importantModule2', 'customModule1', 'customModule2', 'customModule3']);
</script>
<!-- here goes html structure with lot of ng-controller -->
<script>
//controller example
CoreAngular_AppObj.controller('MyControllerX', function($scope, myCustomModule2) {
}
</script>
</html>
It works, but as I have a lot of controllers and I don't know which of them will used, I want to load this list ['customModule1', 'customModule2', 'customModule3'] dynamically
I will glad to get something like this.
<html ng-app='CoreAngular_App'>
<script>
var CoreAngular_AppObj = angular.module('CoreAngular_App', ['importantModule1', 'importantModule2']);
</script>
<!-- here goes html structure with lot of ng-controller -->
<script>
// ADD myCustomModule2 TO CoreAngular_AppObj HERE
//controller example
CoreAngular_AppObj.controller('MyControllerX', function($scope, myCustomModule2) {
}
</script>
</html>
Is it possible? And how?
Thanks
I'll try to make an example of what either may look like.
Inline - from backend logic -
// Create list from rendered array.
var modules = ['customModule1', 'customModule3']; // ex: print json_encode($arrayStr);
// Add a custom module
angular.module('myCustom', modules);
//Inject the custom module
angular.module('CoreApp', ['importantModule1', 'importantModule2', 'myCustom']);
angular.bootstrap docs
Remember to remove ng-app
var app = angular.module('CoreApp', []);
someReadyFunction(){
// figure out which moules here
angular.bootstrap(document, ['CoreApp', 'customModule1', 'customModule3']);
}

Why does coffeescript angular demo fail in jsfiddle when an identical javascript one works?

I was building a jsfiddle angular app in coffeescript. It failed, and I reduced the failure to this minimal one:
<body ng-app="MyApp">
<div ng-controller="MyController">
{{text}}
</div>
</body>
This javascript fiddle works: http://jsfiddle.net/nje7H/
var app = angular.module("MyApp", []);
app.controller("MyController", function($scope) {
$scope.text = "Hello."
});
However, this coffeescript fiddle fails: http://jsfiddle.net/nje7H/1/
app = angular.module "MyApp", []
app.controller "MyController", ($scope) ->
$scope.text = "Hello."
The console shows "Uncaught Error: No module: MyApp"
Why?
jsfiddle uses <script type="text/coffeescript"> elements and a library to compile the coffeescript on the client, which doesn't occur until the dom is ready and the code doesn't execute until after angular bootstraps. It will work if you manually bootstrap angular in your code (fiddle):
angular.bootstrap document.body, ['MyApp']
In a production environment you should be compiling your coffeescript into javascript for the browser and there wouldn't be a problem. See this question.

Resources