How do load the angularJS module into an application? - javascript

I am receiving the following error:
Unhandled exception at line 24, column 180 in
https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js
0x800a139e - JavaScript runtime error: [$injector:nomod]
http://errors.angularjs.org/1.4.8/$injector/nomod?p0=undefined,
I have my scripts loaded within the page and am not referencing any JavaScript files except for the app.js and module for controllers within the project like below:
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="Scripts/someApp.js"></script>
<script src="Scripts/someModule.js"></script>
<title>Box labeling Program</title>
</head>
<body ng-app="someApp">
<div ng-controller="someCtrl">
</div>
</body>
</html>
The angularJS that I thinking I need below (someApp.js):
angular.module('someApp'['someModule'])
.config([function () {
console.log("Config hook")
}])
.run([function () {
console.log("Run the hook");
}])
There seems to be an issue with angular.min.js, it does not seem to know what object it needs from the reference. I have changed the placement of the script to below the body tag, though this does not seem to change anything.
Also, here is the what I suspect that I need to use for the creating controllers,
angular.module('someModule', [])
.config([function () {
console.log("Some Module:: config");
}])
.run([function () {
console.log("Some Module:: running");
}])
.controller('SomeCtrl', ['$scope', function ($scope) {
$scope.theName ="Julie"
}])
}])

If this is your actual code then you are missing a comma between 'someApp' and the injected dependency ['someModule']. Although angular gives pretty generic error messages you can infer something to this point by the fact that it is a runtime error. That suggests an error in code not in logic. it also states: [$injector:nomod]. Which means there is no module to inject.
If this is just an approximation of your code and not the actual code then we really can't help you. I only say this because what you've provided is exceptionally generic and is either an exercise you're performing or your attempt to hide code for some reason. If that's the case then our ability to help is limited.

Related

'Controller' defining separately returns is not a function, got undefined

Don't know why this is not working this time..Previously every where its working bt this time its creating issues like this..
here i've like app.js
var testApp= angular.module('test',[]);
testApp.controller('testCtrl',function($scope){
$scope.testValue='testttttttttt';
})
view file index.html
<div ng-app="test" ng-controller="testCtrl">
{{testValue}}
</div>
it working fine..
but when i make controller file seprately and call it in view
<div ng-app="test" ng-controller="testCtrl">
{{testValue}}
</div>
<script src="testCtrl.js"></script>
it returns its not function, undefined...
but if in app.js
i convert
var testApp= angular.module('test',[]);
to
var testApp= angular.module('test');
it works again..
here, whats the main problem?? like this i can't pass any dependecies.. Any suggestions please..
You're declaring and redeclaring a global variable for your module. This global variable will probably be hoisted or some other kind of javascript execution voodoo that will make your code behave in an unpredictable manner. To protect from this, just use angular's built in module getter call instead of declaring it on the global namespace.
Like so:
App.js
angular.module('testApp', [
// dependencies here'
]);
TestCtrl.js
angular.module('testApp')
.controller(function($scope) {
$scope.testValue = "value";
});
Again, the important distinction here is that angular.module('testApp', []) with the second argument (the dependency list) creates a new module, overwriting whatever testApp was before. On the other hand, angular.module('testApp') called without the second argument simply retrieves the module so that you can add more directives/controllers/config/constants to it.
Also, you should probably ditch stand alone controller, as they're not really considered best practice anymore. The directive/component route is much more in vogue right now.
For a brief overview of current angular best practices, check out John Papa's https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md
Place the controller file after loading the app.js file.
So the content of the app.js will be,
var testApp= angular.module('test',[]);
Controller.js will be,
angular.module('test').controller('testCtrl',function($scope){
$scope.testValue='testttttttttt';
})
In index.html , order will be,
<script src="app.js"></script>
<script src="testCtrl.js"></script>
DEMO

Why does ng-click not work?

Moved this question to this post - Angular events, ng-click, do not work with other libraries Dojo, Knockout, KendoUI, ESRI JSAPI
No matter what I try, ng-click does not work. However, onclick works. Inside the scope, wiring up an on click event dos not work. What is going on?
EDIT: I can call the $scope.myClick() from the command line. But it will not hit the breakpoint. It will show an alert window, but if this is called from within HTML directive, the function is not hit.
EDIT 2: heres a plunker - https://plnkr.co/edit/kK3NmWB9wfOopG7m5MYv?p=preview
EDIT 3: Ok, so the plunker works, but the horrible application I need to add angular to must messing with something in angular. Any ideas what could be breaking Angular in an existing app? This other app uses dojo, dojo loaders, and require.js. Everything works, except for the ng-click event.
EDIT 4: I commented out an Init() call from this application which loads Dojo, Kendo UI, Knockout, and ESRI JSAPI components, and this Angular code with ng-click works. My gut feeling is knockout is messing with this. Is it possible to completely isolate Angular from the rest of this application? Any suggestions?
here is the app:
var myApp = angular.module('myApp ', []);
directive:
myApp.directive('rapidReport',
function () {
return {
restrict: 'E'
}
});
<div class="ls-rapidReports">
<div ng-app="myApp">
<div id="rapidreportCtrl" ng-controller="rrController">
<button type="button" ng-click="myClick()">hehe</button>
</div>
</div>
</div>
controller:
myApp.controller('rrController',
function rrController($scope) {
$scope.myClick = function () {
debugger;
};
});
Here is the problem:
var myApp = angular.module('myApp ', []);
which should be:
var myApp = angular.module('myApp', []); //myApp without space before '
-
EDIT: Now I see it fixed in the plnkr. If you infact try to add the space again in myApp declaration you will see the following error message in the console.
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 the dependencies as the second argument.
As you can deduct from the error log, the app declaration in the script.js wasn't matching with the one in the ng-app directive in index.html, so the app wasn't working.

WebStorm Angular directive scope & HTML

Since I'm new here I'll introduce myself. My name is Tomas from the Netherlands and I have just started coding intensively. Atm I'm working on a project using AngularJS to write me an interactive Curriculum Vitae. I wanted to do this so I have something to show when I apply for jobs.
Thus, some things I might have done harder than they could have just to show what I can do for the moment.
Ok, back to the question. I've run into a problem using an AngularJS directive in my HTML body code.
The .JS file is:
/**
* Created by Tomas on 24-1-2016.
*/
var myApp = angular.module("PersonApp",[])
.controller("TomasInformation", ["$scope", function($scope, $routeParams) {
$scope.tomas = {
firstName: "Thomas",
lastName: "Slepers",
middleNames: "Dirk",
dateOfBirth: new Date("1985","03","18"),
placeOfBirth: "Rosmalen",
city: "Maastricht",
address: ["Banniersborg", "176", "B", "6238 VS"],
telephone: "+31 6386492",
email: "t.example#example.com",
nationality: "Dutch"
};
}])
.directive('personInfo', function() {
return {
restrict: "E",
scope: {
info: "="
},
templateUrl: 'JS/personInfo.html'
};
});
The template .html file I'm calling is:
<ul>
<li>{{info.firstName}} {{info.lastName}} </li>
<li>{{info.firstName}} {{info.middleNames}}</li>
<li>{{info.dateOfBirth | date}}</li>
<li>{{info.placeOfBirth}}</li>
<li>{{info.city}}</li>
<li>{{info.address[0]}} {{info.address[1]}}{{info.address[2]}}, {{info.address[3]}}</li>
<li>{{info.telephone}}</li>
<li>{{info.email}}</li>
<li>{{info.nationality}}</li>
</ul>
And the html-code I'm using in the Index.html main page is:
<div class="right_information" ng-app="PersonApp" ng-controller="TomasInformation">
<person-info info="tomas"></person-info>
</div>
Now the problem is that calling the <person-info> element doesn't give me my first name etc, but only the raw code on my website, e.g. {{info.firstName}}.
I've checked already some things, like whether the Angular Library is loaded (which is the case).
Can somebody see what I am doing wrong? I'm at a loss here.
P.S. I've altered the personal data in the controller so calling/e-mailing will not be of any use :)
Edit: I've done the F12 thing in my browser (Chrome) and saw the following error output, can't seem to understand what it means though.I've added stars in the https since I'm not allowed to post more than 2 links :)
.
angular.js:11655 Error: [$compile:multidir] http://errors.angularjs.org/1.3.15/$compile/multidir?p0=personInfo&p1=personInfo&p2=template&p3=%3Cperson-info%20info%3D%22tomas%22%3E
at Error (native)
at https*://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:6:417
at Na (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:67:19)
at fa (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:62:4)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:65:406
at https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:112:113
at n.$eval (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:126:15)
at n.$digest (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:123:106)
at n.$apply (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:126:293)
at l (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js:81:240)
(anonymous function) # angular.js:11655
And the <head> of the Index.html frontpage is:
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="JS/app.js"></script>
<link type="text/css" rel="stylesheet" href="stylesheet.css"/>
<title></title>
</head>
So I'm pretty sure the angular.min.js is loaded. Because when I remove the <person-info> tags and insert the template code directly, it works well :/
Is this all the code you have in the application? Like Alainlb has shown in the plunkr, this code works.
But the error that you are seeing is caused by colliding directives.
From Angular documentation:
Example scenarios of multiple incompatible directives applied to the
same element include:
Multiple directives requesting isolated scope.
Multiple directives publishing a controller under the same name.
Multiple directives declared with the transclusion option.
Multiple directives attempting to define a template or templateURL.
Check your app for any of these scenarios.
I'm sorry that I have bothered.
It seemed the problem was very simple and your answers gave me the right way to go.
I was reviewing the directive statement and changed, for the sake of testing, the name of the directive from "personInfo" to testTestTest. This due to the fact that the template I'm calling in the directive also is called personInfo, but then with extension HTML.
This obviously did the trick. It seems these statements interfered and now it works and I can continue :)
Thank you for the help :)

The correct order to load Google Client api gapi and angular js

It's kind of tricky how to load js files in an Angular project together with Google Client js api.
This question is talking about the correct order of doing this.
Angular Js and google api client.js (gapi)
And there is an Official Doc talking about this,
https://cloud.google.com/developers/articles/angularjs-cloud-endpoints-recipe-for-building-modern-web-applications/.
One thing in the doc is that it uses window.init() inside of init which will be causing an infinite loop.
As willlma pointed out, we should use a different name for the function.
But I have met an error of
Uncaught TypeError: window.initGAPI is not a function
The project is created by using yeoman generator for angular.
The order of loading js in index.html
<script src="scripts/app.js"></script>
<script src="scripts/controllers/main.js"></script>
<script src="scripts/controllers/about.js"></script>
<script src="https://apis.google.com/js/client.js?onload=init"></script>
app.js(only the latter part of this file):
var init = function(){
console.log("gapi init");
window.initGAPI();
}
main.js:
angular.module('testApp')
.controller('MainCtrl', function ($scope, $window) {
$window.initGAPI = function(){
console.log("controller inti");
}
$scope.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
});
I have put some logs to test and found that the definition for $window.initGAPI is executed before loading the cliet.js which calls window.init, but inside of window.init, window.initGAPI is not defined. It seems in the main controller, defining a function called initGAPI to object window failed.
I think is not so easy to correctly load both libraries each in its way, because both are asynchronous in a different way.
Instead, is easier to let one load the other.
The first and simplier approach is to put the client.js lib at the end of all scripts, and then do a manual Angular bootstrap when the Google library is fully loaded.
Other method could be the opposite, so let Angular create the Google client.js script tag and load the library.
Check this project: https://github.com/canemacchina/angular-google-client
I've create this library to help me using Google client library in Angular, and it use the second method...
I had a similar issue. Perhaps you can try something like this for the init function so that it retries again when the controller is not loaded yet.
function init() {
if (window.initGapi != undefined) {
window.initGapi();
}
else {
setTimeout(init, 500); // wait for 500 ms
}
}

AngularJS: How to add and compile a directive to the dom, from a service

I think what I am trying to do is fairly simple, but I can't seem to determine the correct architecture using Angular.
I'd like to have a MessageCenter, so that any controller or other piece of Angular code can add a message. I thought that the correct way to do this would be with a MessageCenter service. I would inject the service where needed, and call MessageCenter.add(). The problem that I am having is how to compile the cloned DOM directive, since $compile requires a $scope, which I do not have from a service.
Here is what I am trying. I am not sure what the correct approach is for this.
<div>
<div id="msg-proto" message-center-msg class="alert alert-success"></div>
</div>
Then:
.factory('MessageCenter', function($compile) {
var that = {}
that.add = function(type, message) {
var n = $("#msg-proto"),
n2 = n.clone();
n.parent().append($compile(n2));
}
return that;
});
And I am injecting and calling the service:
.controller('SomeCtrl', function(MessageCenter) {
MessageCenter.add('some msg');
});
I have a message-center-msg directive defined that adds some behaviors to the element. But it needs to be $compile'd in order for that to happen, and I am not sure how to make this all work. I only ever end up with "Error: Argument 'scope' is required" from the service.
How can I setup a global message center, that is able to clone/add messages and have the directive on the message dom element processed?
Your service shouldn't interact with the DOM directly as you're trying to do. If I were designing such a system I would:
Have a service which simply takes in messages and either puts them in an array (if you want to support a whole list of messages) or simply remembers the last message (if you only want to support a single message)
Have a controller which gets the message service injected to it and binds the message(s) from the service into its scope
Then have a bit of HTML (or a custom directive) that iterates the messages using the above controller and displays them
Here's what I mean (plunk here: http://plnkr.co/Eps1Gy)
index.html:
<!doctype html>
<html>
<head>
<script src="bower_components/angular/angular.js"></script>
<script src="scripts/app.js"></script>
<script src="scripts/controllers/messages.js"></script>
<script src="scripts/controllers/click.js"></script>
<script src="scripts/services/messageService.js"></script>
</head>
<body ng-app="messagesApp">
<h1>Messages</h1>
<div ng-controller="MessagesCtrl">
<ul ng-repeat="message in messages">
<li>{{message}}</li>
</ul>
</div>
<a ng-href="#" ng-controller="ClickCtrl" ng-click="addMessage()" >Add a new message!</a>
</body>
</html>
messageService.js:
function MessageService() {
this.messages = [];
this.add = function(msg) {
this.messages.push(msg);
}
}
angular.module('messagesApp')
.service('messageService', MessageService);
messages.js:
angular.module('messagesApp')
.controller('MessagesCtrl', function ($scope, messageService) {
$scope.messages = messageService.messages;
});
click.js:
angular.module('messagesApp')
.controller('ClickCtrl', function ($scope, messageService) {
var count = 0;
$scope.addMessage = function() {
messageService.add('Test message ' + count++);
}
});
app.js:
angular.module('messagesApp', [])
.config(function ($routeProvider) {
$routeProvider
.otherwise({
redirectTo: '/'
});
});
Like I said, you can replace the HTML for handling the messages with a custom directive if you want some complex interaction, but the important thing is that you don't try to muck with the view from your service. The service should interact only with a well-defined model.
I implemented something pretty identical a while back and recently made this public as a bower component.
Maybe you can use or work off of it: https://github.com/IanShoe/angular-message-center
Happy coding!
You can open your mind :)
On your call to the MessageCenter move the $scope as parameter like MessageCenter.add("", $scope);
Or ... you can expose the MessageCenter to the scope globally on startup something like this guy suggested

Categories

Resources