Reputation: 31
I'm new to AngularJS and I'm trying to use a .factory that I created in a Controller.
When I leave the Factory out, of the dependency array the code files execute w/o any errors.
However, as soon as I add the name of the Factory to the controller dependency array, I recieve an error that the name of the controller cannot be found.
Would someone be able to help me correct my controller syntax so that the controller can use and execute without errors.
My module, factory and controller are in separate files and they look like this:
angular.module('app', []); // this 'app' is the name of the module. it needs to be referenced in the berrcontroller or any other controller or service that used this module
(function () // using IIFE
{
angular.module('app') // 'app' is the name of the module in the BeerApp.js file.
.factory('BeerFactory', beerFactory);
function beerFactory() {
var _brewer = 'Three Floyds';
var _beer = 'Alpine King';
var getBeer = function () {
return _brewer + ' ' + _beer;
} // getBeer
return {
getBeer: getBeer
};
}// beerFactory
})(); // function(){
(function () // using IIFE
{
angular.module('app') // 'book' is the name of the module in Book.js file.
.controller('BeerController', beerController); // second parameter is the dependency array. since we are using controllerAs syntax,$scope not necessary
// since using vm, have easy naming for all variables
function beerController(BeerFactory) {
var vm = this;
vm.beer = 'generic beer';
vm.title = "Controller Using a Service";
activate();
function activate() {
return getBeer;
} // activate
function getBeer() {
return beerFactory.getBeer().then(function (data) {
vm.beer = data;
return vm.beer
});
}//getBeer function
}
})();
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- tell ie to assume the highest supported version of its rendering engine. -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- content tells the device what width to use. When left out, content appears small because device assumes desktop version -->
<!-- initial-scale sets the degree to be scaled up by default. -->
<!-- how do you prevent pinch zoom. -->
<title>Learning AngularJS</title>
<!-- Bootstrap -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap-theme.min.css" rel="stylesheet" />
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<!-- add Normalize to make page look the same on all browsers. -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.2/normalize.css" rel="stylesheet" />
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<!-- custom styles-->
<style>
</style>
</head>
<body>
<header><h1>Service in a controller</h1></header>
<div ng-app="app">
<div ng-controller="BeerController as vm">
<h1>{{vm.title}}</h1>
{{vm.beer}} is the beer company and name
</div>
</div>
<footer>
<p>Chieko's beer app.</p>
</footer>
<!-- all of the angular js file resources -->
<script src="/Scripts/angular.min.js"></script>
<script src="BeerApp.js"></script>
<script src="BeerFactory.js"></script>
<script src="BeerController.js"></script>
</body>
</html>
Upvotes: 2
Views: 77
Reputation: 31
Thanks all for your kind help. Here's the corrected version of the Factory:
(function () // using IIFE
{
angular.module('app') // 'book' is the name of the module in the Book.js file.
.factory('BeerFactory', beerFactory);
function beerFactory() {
var _brewer = 'Three Floyds';
var _beer = 'Alpine King';
var getBeer = function () {
return _brewer + ' ' + _beer;
} // getBeer
return {
getBeer: getBeer
};
}// beerFactory
})(); // function(){
This is the correct version of the controller:
(function () // using IIFE
{
angular.module('app') // 'book' is the name of the module in Book.js file.
.controller('BeerController', ['BeerFactory', beerController]); // second parameter is the dependency array. since we are using controllerAs syntax,$scope not necessary
// since using vm, have easy naming for all variables
function beerController(BeerFactory) {
var vm = this;
vm.beer = '';
vm.title = "Controller Using a Service";
activate();
function activate() {
return getBeer();
//vm.beer = BeerFactory.getBeer();
} // activate
function getBeer(beer) {
vm.beer = BeerFactory.getBeer();
return vm.beer;
}
} })();
The the corresponding html page:
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- tell ie to assume the highest supported version of its rendering engine. -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- content tells the device what width to use. When left out, content appears small because device assumes desktop version -->
<!-- initial-scale sets the degree to be scaled up by default. -->
<!-- how do you prevent pinch zoom. -->
<title>Learning AngularJS</title>
<!-- Bootstrap -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap-theme.min.css" rel="stylesheet" />
<!-- add Normalize to make page look the same on all browsers. -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.2/normalize.css" rel="stylesheet" />
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<!-- custom styles-->
<style>
</style>
</head>
<body>
<header><h1>Hour 07</h1></header>
<div ng-app="app">
<div ng-controller="BeerController as vm">
<h1>{{vm.title}}</h1>
{{vm.beer}} is the beer company and name
</div>
</div>
<footer>
<p>Chieko's beer app.</p>
</footer>
<!-- all of the angular js file resources -->
<script src="/Scripts/angular.min.js"></script>
<script src="BeerApp.js"></script>
<script src="BeerFactory.js"></script>
<script src="BeerController.js"></script>
</body>
</html>
There were no changes to the App.js file.
Notice that I am not using the '.then(function(data){}) b/c the application didn't work with that part of the code.
Upvotes: 0
Reputation: 2683
You make everything write except some small mistakes:
first you have to call your IIFE factore with ()
at the end.
And then you have to care about upper letters. You must inject your factory or controller the same way as you define them.
And last but not least you have to define your controller like
.controller('BeerController', beerController);
angular.module('app', []); // this 'app' is the name of the module. it needs to be referenced in the berrcontroller or any other controller or service that used this module
(function () // using IIFE
{
angular.module('app') // 'app' is the name of the module in the BeerApp.js file.
.factory('BeerFactory', beerFactory);
function beerFactory() {
var _brewer = 'Three Floyds';
var _beer = 'Alpine King';
var getBeer = function () {
return _brewer + ' ' + _beer;
} // getBeer
return {
getBeer: getBeer
};
}// beerFactory
})(); // function(){
(function () // using IIFE
{
angular.module('app') // 'book' is the name of the module in Book.js file.
.controller('BeerController', beerController); // second parameter is the dependency array. since we are using controllerAs syntax,$scope not necessary
// since using vm, have easy naming for all variables
function beerController(BeerFactory) {
var vm = this;
vm.beer = 'generic beer';
vm.title = "Controller Using a Service";
activate();
function activate() {
return getBeer;
} // activate
function getBeer() {
return beerFactory.getBeer().then(function (data) {
vm.beer = data;
return vm.beer
});
}//getBeer function
}
})();
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- tell ie to assume the highest supported version of its rendering engine. -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- content tells the device what width to use. When left out, content appears small because device assumes desktop version -->
<!-- initial-scale sets the degree to be scaled up by default. -->
<!-- how do you prevent pinch zoom. -->
<title>Learning AngularJS</title>
<!-- Bootstrap -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap-theme.min.css" rel="stylesheet" />
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<!-- add Normalize to make page look the same on all browsers. -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.2/normalize.css" rel="stylesheet" />
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<!-- custom styles-->
<style>
</style>
</head>
<body>
<header><h1>Service in a controller</h1></header>
<div ng-app="app">
<div ng-controller="BeerController as vm">
<h1>{{vm.title}}</h1>
{{vm.beer}} is the beer company and name
</div>
</div>
<footer>
<p>Chieko's beer app.</p>
</footer>
<!-- all of the angular js file resources -->
<script src="/Scripts/angular.min.js"></script>
<script src="BeerApp.js"></script>
<script src="BeerFactory.js"></script>
<script src="BeerController.js"></script>
</body>
</html>
Upvotes: 0
Reputation: 3138
Try this
BeerApp.js
var myApp = angular.module('app', []);
BeerFactory.js
myApp.factory('BeerFactory', beerFactory);
function beerFactory() {
var _brewer = 'Three Floyds';
var _beer = 'Alpine King';
var getBeer = function () {
return _brewer + ' ' + _beer;
} // getBeer
return {
getBeer: getBeer
};
}// beerFactory
BeerController.js
myApp.controller('BeerController', ['$scope', 'BeerFactory' function($scope, BeerFactory,) {
var vm = this;
vm.beer = 'generic beer';
vm.title = "Controller Using a Service";
activate();
function activate() {
return getBeer;
} // activate
function getBeer() {
return beerFactory.getBeer().then(function (data) {
vm.beer = data;
return vm.beer
});
}//getBeer function
}]);
Upvotes: 0
Reputation: 889
The actual controller function needs to be at the end of the array, and dependencies you're passing into the controller should be strings within the array, not objects
.controller('BeerController', ['beerFactory', beerController]);
Upvotes: 1
Reputation: 1861
When you write:
.controller('BeerController', ['beerController', beerFactory]);
you are actually telling Angular to instantiate a Controller passing it beerController
which of course doesn't exist yet.
Try this:
.controller('BeerController', ['beerFactory', beerController]);
Upvotes: 0