Properly use custom angularjs service, function not defined error - javascript

I created my own service for some util methods. The idea was to simply inject the utilsservice into the modules where I need the methods. The Problem is I get an ReferrenceError: myFunction is not defined.
I think it has to do with the wrong injecting of the service, but i can't figute out myself what's wrong with my approach.
The service i made:
angular.module('utils',[]).service('UtilsService',function(){
this.myFunction = function(){};
});
In my app.js file i have following structure:
(function(){
angular.module('utils',[]);
angular.module('translation',[]);
var app = angular.module('myApp',['translation','utils']);
app.controller('myController',['$http',function($http,UtilsService){
UtilsService.myFunction();
}]);
});
The order I included the scripts in my .html file:
<script type="text/javascript" src="../Libraries/angular.min.js"></script>
<script type="text/javascript" src="../js/angular-js/services/utilService.js"></script>
<script type="text/javascript" src="../js/angular-js/app.js"></script>
<script type="text/javascript" src="../js/angular-js/translate.js"></script>
I already tried to change the order but it doesn't make any difference.
I am thankfull for any advice you may have!

Please try the below. You will need to change the script references to point to the files where you have them. Once the index.html file has loaded, you should see the output "you called myFunction()" in the console window. That is being printed from within the service which shows it's being called correctly. I've also created a fiddle
index.html:
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>Directives</title>
</head>
<body>
<div ng-controller="myController"></div>
<script src="angular.js"></script>
<script src="app.js"></script>
<script src="utilsService.js"></script>
</body>
</html>
app.js (I have moved the code out of the function you created since it wasn't working. Also, you had a typo for spelling anguar on the line that begins with var app. I have also removed the dependency for translation in my code since I didn't create any module by that name):
(function(){
//angular.module('utils',[]);
//angular.module('translation',[]);
});
var app = angular.module('myApp',['utils']);
app.controller('myController',['$scope', 'UtilsService',function($scope,UtilsService){
UtilsService.myFunction();
}]);
utilsService.js:
angular.module('utils',[])
.service('UtilsService',function(){
this.myFunction = function(){ console.log ('you called myFunction()')};
});

Related

Cannot call module's function after browserify

I'm trying to make simple page with JS module that will do something with the page. I need to use node.js's modules so I'm learning how to browserify works.
My HTML:
<!doctype html>
<html>
<head>
<script src="js/bundle.js" type="text/javascript"></script>
</head>
<body>
<p>Hello world!</p>
<script type="text/javascript">
var test = require("./test.js");
test.init();
</script>
</body>
</html>
This is my JavaScript (test.js):
"use strict";
alert("here1");
var init = function() {
alert("here2");
}
exports.init = init
I'm making a bundle with:
browserify.cmd test.js -o bundle.js
When I'm trying to open the page it shows "here1" but doesn't show "here2".
In browser's console I see:
Uncaught ReferenceError: require is not defined index.html:9
Any ideas how to make module's function (init) work well?
You need to put all JavaScript code which contains anything from Node in the test.js file which you are then converting with the browserify into te bundle.js. In your example you are using a Node function require in the index.html which is not going to be converted. Browser then sees function require() which he doesn't know and this is where the problem is hidden.
Simply told: all your javascript code (containing Node) must be included in your index.html as a single bundle.js which is a browserifed result from your source files.
EDIT
Browserify doesn't (by default) allow you to call any browserified function out of the browserified code. But you can make it available by attaching the function into window scope.
This is test.js (which is then converted to bundle.js by browserify) and index.html
"use strict";
alert("here1");
window.init = function() {
alert("here2");
}
<!doctype html>
<html>
<head>
<script src="js/bundle.js" type="text/javascript"></script>
</head>
<body>
<p>Hello world!</p>
<script type="text/javascript">
init();
</script>
</body>
</html>

create controller in ng-view page

I want to manage my controller specific to an ng-view page, therefore I put the controller in ng-view page and used that controller specific to that page only. However, the code does not show what it should show from that controller.
Here is my case.
I split my code into 3 files, which are "mainfile.php", "page1file.php", and "page2file.php". "mainfile.php" contains main page which routes to page 1 and page 2. To compare the results, I created different conditions for those 2 pages. "page1file.php" uses controller which has been defined in "mainfile.php", while "page2file.php" uses controller which is defined in the page itself.
In this circumtances, "page1file.php" successfully shows what I want, but "page2file.php" does not show what it should show. Please help me and give a very simple explanation and a simple solution since I'm very new to angularjs.
Here is my code. You can just copy them and run it on your php server.
mainfile.php :
<!DOCTYPE html>
<html>
<head>
<title>learn angular routing</title>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.min.js"></script>
<script type="text/javascript">
function routeReload($scope) {
$scope.routeReloading = function(){
window.location.reload();
};
}
routeReload.$inject = ['$scope'];
function routeConfig($routeProvider) {
$routeProvider
.when('/one',{
templateUrl:'page1file.php'
})
.when('/two',{
templateUrl:'page2file.php'
})
;
}
routeConfig.$inject=['$routeProvider'];
function testOne($scope) {
$scope.name = "page one";
}
testOne.$inject = ['$scope'];
var testNgView = angular.module('testNgView',['ngRoute']);
testNgView.config(routeConfig);
testNgView.controller('routeReload',routeReload);
testNgView.controller('testOne',testOne);
</script>
</head>
<body>
<div ng-app="testNgView">
<div ng-controller="routeReload">
View page <a ng-click="routeReloading();" href="#one">one</a> or
<a ng-click="routeReloading();" href="#two">two</a>
<div ng-view></div>
</div>
</div>
</body>
</html>
page1file.php :
<div ng-controller="testOne">
This is {{name}}
</div>
page2file.php :
<script type="text/javascript">
function testTwo($scope) {
$scope.name = "page two";
}
testTwo.$inject = ['$scope'];
testNgView.controller('testTwo',testTwo);
</script>
<div ng-controller="testTwo">
This is {{name}}
</div>
I don't think you can inline script modules in your view templates. Have a look at this working version of your app, the way I would organize it:
http://plnkr.co/edit/nSsagK1Y04akNJyMToah?p=preview
You can use .php files in place of the .html files, that shouldn't make a difference.
So your main file should look something like this:
<!DOCTYPE html>
<html>
<head>
<title>learn angular routing</title>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.min.js"></script>
</head>
<body>
<div ng-app="testNgView">
View page one
or two
<ng-view></ng-view>
</div>
<script src="app.module.js"></script>
<script src="app.routes.js"></script>
<script src="views/page1/controller.js"></script>
<script src="views/page2/controller.js"></script>
</body>
</html>
If your goal is to use PHP to dynamically render your controllers, see the answer to this SO question: Angularjs: server side (php) rendering and data binding client side after an event
You may also be interested in this article, about loading Angular components after the application has been bootstrapped: http://www.bennadel.com/blog/2553-loading-angularjs-components-after-your-application-has-been-bootstrapped.htm
TL;DR: You would need to store a reference to $controllerProvider in the config phase, and then call $controllerProvider.register('MyController', MyController) in your inline script. I'm not sure how I feel about that though...

Angular error Error: [ng:areq]

I'm new on Angular, I'd like to know what's wrong with my code, because the browser shows me this error: Error: [ng:areq] http://errors.angularjs.org/1.4.7/ng/areq?p0=HelloWorldCtrl&p1=not%20a%20function%2C%20got%20undefined
at Error (native)
y el codigo es este:
<!doctype html>
<html ng-app>
<head>
<title>Angular Practice</title>
</head>
<body>
<h1 ng-controller="HelloWorldCtrl">{{helloMessage}}</h1>
<script src="angular.min.js"></script>
<script type="text/javascript">
function HelloWorldCtrl($scope) {
$scope.helloMessage = "Angular Practice";
}
</script>
</body>
</html>
Thanks a lot.
Your HelloWorldCtrl isn't defined.
This is because you're not binding it as an angular module with a controller attached.
ng-controller looks for a definition like this:
angular.module('HelloWorldCtrl', [])
.controller('HelloWorldCtrl', function($scope){
$scope.helloMessage = "Angular Practice";
});
That controller also needs to be assigned to the main app, which you need to reference on that ng-app directive, i.e.
<html ng-app="helloWorldApp">
Which should point to a module you create as such:
var helloWorldApp = angular.module('helloWorldApp ', [
'HelloWorldCtrl'
])
Notice, I'm including a 'HelloWorldCtrl' reference as an item for the second parameter on that module definition. This tells angular to load that controller as a resource which you can then reference through that ng-controller directive.
EDIT:
Did a little research on my mention of adding 'HelloWorldCtrl' as an item in the array above and wanted to elaborate a little bit on why my solution is slightly different than the other answer here. The way I've set it up, is such that 'HelloWorldCtrl' is a separate module. In this case you do need to reference it in the way I have. This tells the app module that it depends on the 'HelloWorldCtrl' module. In the answer below mine is binding that controller directly to the app, in which case this isn't necessary.
Steps to make it working,
Add a ng-app directive to your <html> tag
Define your module app in the script below.
Define your controller HelloWorldCtrl as below.
Check this Plunker - http://plnkr.co/edit/w8RWm6nr1WgvhX3BbGUE?p=preview
!DOCTYPE html>
<html ng-app="app">
<head>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.0-beta.4/angular.min.js"></script>
</head>
<h1 ng-controller="HelloWorldCtrl">{{helloMessage}}</h1>
<script type="text/javascript">
angular.module('app', []);
angular.module('app').controller('HelloWorldCtrl', [ '$scope', function($scope) {
$scope.helloMessage = "Angular Practice";
}]);
</script>
</html>

How to use a controller in an other file in Angularjs

I'm used to code with Java with many files with object paradigm and MVC pattern with packages.
And I begin with AngularJS, I'm trying to enable a simple index.html who use a controller in javascript file but doesn't work.
my html file : index.html
<html ng-app="carre">
<head>
<script src="js/angular.js"></script>
<script src="js/CalculCtrl.js"></script>
<script>
var ctrl = angular.module('carre',[]);
</script>
</head>
<body ng-controller="CalculCtrl">
<div>{{2+2}}</div>
<p>{{temps}}</p>
</body></html>
My javascript file as controller located at js/CalculCtrl.js
carre.controller('CalculCtrl', function($scope)
{
$scope.temps = 'pluie';
}
)
What's wrong here please ?
Thanks in advance.
Rename carre.controller(...) to ctrl.controller
Ctrl is the name of the variable holding a reference to your module, carre is the name you have given it for reference in the ng-app directive.
Edit: Also, I recommend you get the Batarang extension for Chrome, it adds a page to the Developer Tools for debugging Angular apps. Very helpful tool to have.
You should invert the file inclusion and the module declaration:
<html ng-app="carre">
<head>
<script src="js/angular.js"></script>
<script>
var carre = angular.module('carre',[]);
</script>
<script src="js/CalculCtrl.js"></script>
</head>
Also, because you are using a variable called carre inside CalculCtrl.js, you should rename the variabile assignd when creating the module, from ctrl to carre:
var carre = angular.module('carre',[]);
You have created module ctrl and using carre to refer it.And script sequence is wrong.The right answer is
index.html
<html>
enter code here<html ng-app="carre">
<head>
<script src="js/angular.js"></script>
<script>
var carre = angular.module('carre',[]);
</script>
<script src="js/CalculCtrl.js"></script>
</head>
<body ng-controller="CalculCtrl">
<div>{{2+2}}</div>
<p>{{temps}}</p>
</body></html>
CalculCtrl.js
carre.controller('CalculCtrl', function($scope)
{
$scope.temps = 'pluie';
}
);
As an alternative to the other answers you could create your CalculCtrl in it's own module and then depend on that module when declaring carre.
angular.module('Calcul', [])
.controller('CalculCtrl', function($scope)
{
$scope.temps = 'pluie';
}
);
and then for carre
angular.module('carre', ['Calcul']);
In this way you don't need to re-order your script tags as they are
the answer is here
index.html
<html ng-app="AppliName">
<head>
<--! we load angularjs -->
<script src="js/angular.js"></script>
<--! we load our controller in an other javascript file -->
<script src="js/mesControllers.js"></script>
</head>
<body ng-controller="myCtrl">
<p>time is : {{temps}} </p>
</body>
</html>
mesControllers.js located at js/mesControllers.js
var AppliName = angular.module('AppliName', []);
AppliName.controller('myCtrl', function ($scope) {
$scope.temps = 'pluie';
});
run and Keep calm it working now ;p

Uncaught ReferenceError when accessing an object from another JS file

I have various JS libraries in my web application, which are loaded before my main JS file (main.js). One of these libraries is jshashtable, but when I try to create a new Hashtable object in main.js, Google Chrome and Firefox throw a ReferenceError, complaining that the variable does not exist.
Here is the <head> of the application:
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="/static/jquery-1.4.4.min.js"></script>
<script type="text/javacsript" src="/static/jshashtable-2.1.js"></script>
<script type="text/javascript" src="/static/main.js"></script>
Here is the problem line in main.js:
posts = new Hashtable();
This line is inside a function called init which is called when the page has finished loading (using the jquery $(document).ready() function).
Any reason why Hashtable is not global? Google maps and jquery objects work with no such problem. The source of jshashtable can be seen on Google code.
Updated answer: The problem is that you've got a typo in the script tag:
<script type="text/javacsript" src="/static/jshashtable-2.1.js"></script>
<!-- ^^---- here (the letters are transposed) -->
I couldn't understand why you would be running into a problem and decided to actually copy-and-paste your script tags and replicate the structure exactly on my machine. And things stopped working and my world tilted 3° counter-clockwise until I finally stared at them long enough to see it.
Provided that the jshashtable code really is at /static/jshashtable-2.1.js and your server is serving it up correctly (double-check on Chrome's resources tab in the dev tools), I can't see any reason for that. Your scripts are in the right order, and jshashtable's docs show using a global Hashtable (and the code link you gave clearly shows it creating one).
Edit: I've just replicated that same structure (same scripts, same order, using jQuery(document).ready(function() { ... });) on my own server, and am not having that problem. I can create a Hashtable and use its functions.
My HTML:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Test Page</title>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type='text/javascript' src='jquery-1.4.4.js'></script>
<script type='text/javascript' src='jshashtable-2.1.js'></script>
<script type='text/javascript' src='main.js'></script>
</head>
<body>
</body>
</html>
My main.js:
jQuery(document).ready(function() {
try {
var ht = new Hashtable();
display("typeof ht = " + typeof ht);
display("ht.size() = " + ht.size());
}
catch (e) {
display("Exception: " + e);
}
function display(msg)
{
$("<p>").html(msg).appendTo(document.body);
}
});
Only difference is I'm not using a /static prefix, and I'm absolutely certain that makes no difference.

Categories