I keep getting that error and i have no idea why:
Error: [$injector:modulerr] Failed to instantiate module starter due to: [$injector:modulerr] Failed to instantiate module starter.controllers due to: [$injector:modulerr] Failed to instantiate module starter.services due to: [$injector:nomod] Module 'starter.services' 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.
calendar.html file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
</head>
<body ng-app="starter">
<ion-pane ng-controller="CalendarCtrl">
<ion-content>
<div class="card" ng-repeat="event in events">
<div class="item item-divider">
{{event.title}}
</div>
<div class="item item-text-wrap">
{{ event.description }}
<p/>
<strong>When: {{ event.date | date:'short' }}</strong>
</div>
</div>
</ion-content>
</ion-pane>
</body>
</html>
services.js file:
angular.module('starter.services', [])
.factory('Events', function($q) {
var incrementDate = function (date, amount) {
var tmpDate = new Date(date);
tmpDate.setDate(tmpDate.getDate() + amount)
return tmpDate;
};
//create fake events, but make it dynamic so they are in the next week
var fakeEvents = [];
fakeEvents.push(
{
"title":"Meetup on Ionic",
"description":"We'll talk about beer, not Ionic.",
"date":incrementDate(new Date(), 1)
}
);
fakeEvents.push(
{
"title":"Meetup on Beer",
"description":"We'll talk about Ionic, not Beer.",
"date":incrementDate(new Date(), 2)
}
);
fakeEvents.push(
{
"title":"Ray's Birthday Bash",
"description":"Celebrate the awesomeness of Ray",
"date":incrementDate(new Date(), 4)
}
);
fakeEvents.push(
{
"title":"Code Review",
"description":"Let's tear apart Ray's code.",
"date":incrementDate(new Date(), 5)
}
);
var getEvents = function() {
var deferred = $q.defer();
deferred.resolve(fakeEvents);
return deferred.promise;
}
return {
get:getEvents
};
});
controller.js file:
angular.module('starter.controllers', ['starter.services'])
.controller('AppCtrl', function ($scope, $ionicModal, $timeout) {
// With the new view caching in Ionic, Controllers are only called
// when they are recreated or on app start, instead of every page change.
// To listen for when this page is active (for example, to refresh data),
// listen for the $ionicView.enter event:
//$scope.$on('$ionicView.enter', function(e) {
//});
// Form data for the login modal
$scope.loginData = {};
// Create the login modal that we will use later
$ionicModal.fromTemplateUrl('templates/login.html', {
scope: $scope
}).then(function (modal) {
$scope.modal = modal;
});
// Triggered in the login modal to close it
$scope.closeLogin = function () {
$scope.modal.hide();
};
// Open the login modal
$scope.login = function () {
$scope.modal.show();
};
// Perform the login action when the user submits the login form
$scope.doLogin = function () {
console.log('Doing login', $scope.loginData);
// Simulate a login delay. Remove this and replace with your login
// code if using a login system
$timeout(function () {
$scope.closeLogin();
}, 1000);
};
})
.controller('CalendarCtrl', ['starter.services', function ($scope, Events) {
Events.get().then(function (events) {
console.log("events", events);
$scope.events = events;
})
}])
.controller('PlaylistsCtrl', function ($scope) {
$scope.playlists = [
{title: 'Reggae', id: 1},
{title: 'Chill', id: 2},
{title: 'Dubstep', id: 3},
{title: 'Indie', id: 4},
{title: 'Rap', id: 5},
{title: 'Cowbell', id: 6}
];
})
.controller('PlaylistCtrl', function ($scope, $stateParams) {
});
app.js file:
// Ionic Starter App
// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
// 'starter.controllers' is found in controllers.js
angular.module('starter', ['ionic', 'starter.controllers','starter.services'])
.run(function ($ionicPlatform) {
$ionicPlatform.ready(function () {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
})
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/menu.html',
controller: 'AppCtrl'
})
.state('app.search', {
url: '/search',
views: {
'menuContent': {
templateUrl: 'templates/search.html'
}
}
})
.state('app.browse', {
url: '/browse',
views: {
'menuContent': {
templateUrl: 'templates/browse.html'
}
}
})
.state('app.calendar', {
url: '/calendar',
views: {
'menuContent': {
templateUrl: 'templates/calendar.html',
controller: 'CalendarCtrl'
}
}
})
.state('app.playlists', {
url: '/playlists',
views: {
'menuContent': {
templateUrl: 'templates/playlists.html',
controller: 'PlaylistsCtrl'
}
}
})
.state('app.single', {
url: '/playlists/:playlistId',
views: {
'menuContent': {
templateUrl: 'templates/playlist.html',
controller: 'PlaylistCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/app/playlists');
});
I keep getting that error and i have no idea why:
Error: [$injector:modulerr] Failed to instantiate module starter due to: [$injector:modulerr] Failed to instantiate module starter.controllers due to: [$injector:modulerr] Failed to instantiate module starter.services due to: [$injector:nomod] Module 'starter.services' 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.
calendar.html file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
</head>
<body ng-app="starter">
<ion-pane ng-controller="CalendarCtrl">
<ion-content>
<div class="card" ng-repeat="event in events">
<div class="item item-divider">
{{event.title}}
</div>
<div class="item item-text-wrap">
{{ event.description }}
<p/>
<strong>When: {{ event.date | date:'short' }}</strong>
</div>
</div>
</ion-content>
</ion-pane>
</body>
</html>
services.js file:
angular.module('starter.services', [])
.factory('Events', function($q) {
var incrementDate = function (date, amount) {
var tmpDate = new Date(date);
tmpDate.setDate(tmpDate.getDate() + amount)
return tmpDate;
};
//create fake events, but make it dynamic so they are in the next week
var fakeEvents = [];
fakeEvents.push(
{
"title":"Meetup on Ionic",
"description":"We'll talk about beer, not Ionic.",
"date":incrementDate(new Date(), 1)
}
);
fakeEvents.push(
{
"title":"Meetup on Beer",
"description":"We'll talk about Ionic, not Beer.",
"date":incrementDate(new Date(), 2)
}
);
fakeEvents.push(
{
"title":"Ray's Birthday Bash",
"description":"Celebrate the awesomeness of Ray",
"date":incrementDate(new Date(), 4)
}
);
fakeEvents.push(
{
"title":"Code Review",
"description":"Let's tear apart Ray's code.",
"date":incrementDate(new Date(), 5)
}
);
var getEvents = function() {
var deferred = $q.defer();
deferred.resolve(fakeEvents);
return deferred.promise;
}
return {
get:getEvents
};
});
controller.js file:
angular.module('starter.controllers', ['starter.services'])
.controller('AppCtrl', function ($scope, $ionicModal, $timeout) {
// With the new view caching in Ionic, Controllers are only called
// when they are recreated or on app start, instead of every page change.
// To listen for when this page is active (for example, to refresh data),
// listen for the $ionicView.enter event:
//$scope.$on('$ionicView.enter', function(e) {
//});
// Form data for the login modal
$scope.loginData = {};
// Create the login modal that we will use later
$ionicModal.fromTemplateUrl('templates/login.html', {
scope: $scope
}).then(function (modal) {
$scope.modal = modal;
});
// Triggered in the login modal to close it
$scope.closeLogin = function () {
$scope.modal.hide();
};
// Open the login modal
$scope.login = function () {
$scope.modal.show();
};
// Perform the login action when the user submits the login form
$scope.doLogin = function () {
console.log('Doing login', $scope.loginData);
// Simulate a login delay. Remove this and replace with your login
// code if using a login system
$timeout(function () {
$scope.closeLogin();
}, 1000);
};
})
.controller('CalendarCtrl', ['starter.services', function ($scope, Events) {
Events.get().then(function (events) {
console.log("events", events);
$scope.events = events;
})
}])
.controller('PlaylistsCtrl', function ($scope) {
$scope.playlists = [
{title: 'Reggae', id: 1},
{title: 'Chill', id: 2},
{title: 'Dubstep', id: 3},
{title: 'Indie', id: 4},
{title: 'Rap', id: 5},
{title: 'Cowbell', id: 6}
];
})
.controller('PlaylistCtrl', function ($scope, $stateParams) {
});
app.js file:
// Ionic Starter App
// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
// 'starter.controllers' is found in controllers.js
angular.module('starter', ['ionic', 'starter.controllers','starter.services'])
.run(function ($ionicPlatform) {
$ionicPlatform.ready(function () {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
})
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/menu.html',
controller: 'AppCtrl'
})
.state('app.search', {
url: '/search',
views: {
'menuContent': {
templateUrl: 'templates/search.html'
}
}
})
.state('app.browse', {
url: '/browse',
views: {
'menuContent': {
templateUrl: 'templates/browse.html'
}
}
})
.state('app.calendar', {
url: '/calendar',
views: {
'menuContent': {
templateUrl: 'templates/calendar.html',
controller: 'CalendarCtrl'
}
}
})
.state('app.playlists', {
url: '/playlists',
views: {
'menuContent': {
templateUrl: 'templates/playlists.html',
controller: 'PlaylistsCtrl'
}
}
})
.state('app.single', {
url: '/playlists/:playlistId',
views: {
'menuContent': {
templateUrl: 'templates/playlist.html',
controller: 'PlaylistCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/app/playlists');
});
Share
Improve this question
asked Jun 21, 2016 at 9:08
osumatuosumatu
4421 gold badge8 silver badges25 bronze badges
5
- there are lots of errors you need to fix here. I will be posting my answer in a while. see if it helps you. – Sunil Lama Commented Jun 21, 2016 at 10:02
- @AlexRumbaNicked i've changed my calendar.html page to only <ion-content> part and i've included everything in my index.html page but now i get the error: Error: [$injector:unpr] Unknown provider: starter.servicesProvider <- starter.services <- CalendarCtrl – osumatu Commented Jun 21, 2016 at 10:04
-
.controller('CalendarCtrl', ['starter.services', function ($scope, Events) {
this line is wrong, you try to inject module into controller, it should be:.controller('CalendarCtrl', ['$scope', 'Events', function ($scope, Events) {
– maurycy Commented Jun 21, 2016 at 10:07 - @osumatu, oh so you got upto that point, well check my answer of controller.js file and you will find the answer on where you are wrong. – Sunil Lama Commented Jun 21, 2016 at 10:11
- @maurycy i get that when i try to do it: ionic.bundle.js:26794Error: [$injector:unpr] Unknown provider: EventsProvider <- Events <- CalendarCtrl – osumatu Commented Jun 21, 2016 at 10:12
5 Answers
Reset to default 4Firstly, you jinxed your calendar.html
with index.html
. I remend you to separate your index.html
and calendar.html
.
Your starter.controllers injection in app.js
was throwing error because of that.
Secondly, after you have injected the starter.services
in app.js
, you don't need to inject it in every controller file you create although it will not throw error.
Thirdly, your injection of starter.services
factory into the controller is just wrong in this case. Your code for services.js
is fine though. I have changed the app.js
to point to the calendar page directly at first.
Follow the below and you are good to go:
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn./font-awesome/4.4.0/css/font-awesome.min.css">
<link href="css/style.css" rel="stylesheet">
<!-- IF using Sass (run gulp sass first), then unment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
<script src="js/controllers/controllers.js"></script>
<script src="js/services.js"></script>
</head>
<body ng-app="starter">
<ion-nav-view></ion-nav-view>
</body>
</html>
calendar.html
<ion-pane ng-controller="CalendarCtrl">
<ion-content>
<div class="card" ng-repeat="event in events">
<div class="item item-divider">
{{event.title}}
</div>
<div class="item item-text-wrap">
{{ event.description }}
<p/>
<strong>When: {{ event.date | date:'short' }}</strong>
</div>
</div>
</ion-content>
</ion-pane>
controller.js
angular.module('starter.controllers', [])
.controller('AppCtrl', function ($scope, $ionicModal, $timeout) {
// With the new view caching in Ionic, Controllers are only called
// when they are recreated or on app start, instead of every page change.
// To listen for when this page is active (for example, to refresh data),
// listen for the $ionicView.enter event:
//$scope.$on('$ionicView.enter', function(e) {
//});
// Form data for the login modal
$scope.loginData = {};
// Create the login modal that we will use later
$ionicModal.fromTemplateUrl('templates/login.html', {
scope: $scope
}).then(function (modal) {
$scope.modal = modal;
});
// Triggered in the login modal to close it
$scope.closeLogin = function () {
$scope.modal.hide();
};
// Open the login modal
$scope.login = function () {
$scope.modal.show();
};
// Perform the login action when the user submits the login form
$scope.doLogin = function () {
console.log('Doing login', $scope.loginData);
// Simulate a login delay. Remove this and replace with your login
// code if using a login system
$timeout(function () {
$scope.closeLogin();
}, 1000);
};
})
.controller('CalendarCtrl', function ($scope, Events) {
Events.get().then(function (events) {
console.log("events", events);
$scope.events = events;
})
})
.controller('PlaylistsCtrl', function ($scope) {
$scope.playlists = [
{title: 'Reggae', id: 1},
{title: 'Chill', id: 2},
{title: 'Dubstep', id: 3},
{title: 'Indie', id: 4},
{title: 'Rap', id: 5},
{title: 'Cowbell', id: 6}
];
})
.controller('PlaylistCtrl', function ($scope, $stateParams) {
});
app.js
// Ionic Starter App
// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
// 'starter.controllers' is found in controllers.js
angular.module('starter', ['ionic', 'starter.controllers','starter.services'])
.run(function ($ionicPlatform) {
$ionicPlatform.ready(function () {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
})
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/menu.html',
controller: 'AppCtrl'
})
.state('app.search', {
url: '/search',
views: {
'menuContent': {
templateUrl: 'templates/search.html'
}
}
})
.state('app.browse', {
url: '/browse',
views: {
'menuContent': {
templateUrl: 'templates/browse.html'
}
}
})
.state('app.calendar', {
url: '/calendar',
views: {
'menuContent': {
templateUrl: 'templates/calendar.html',
controller: 'CalendarCtrl'
}
}
})
.state('app.playlists', {
url: '/playlists',
views: {
'menuContent': {
templateUrl: 'templates/playlists.html',
controller: 'PlaylistsCtrl'
}
}
})
.state('app.single', {
url: '/playlists/:playlistId',
views: {
'menuContent': {
templateUrl: 'templates/playlist.html',
controller: 'PlaylistCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/app/calendar');
});
Please change order of below script include in calendar.html
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
with
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
<script src="js/app.js"></script>
Let me know if this is not working also you can provide jsfiddle where i can help you exactly.
if this solved i can explain that modules should register first and then should use anywhere.
I mean this will work same like variable which is not hoisted. if we injecting/using module A in module B before doing this we must register Module A that is why we need to change order here.
check your controller
angular.module('starter.controllers', ['starter.services'])
it should be like this
angular.module('starter.controllers', [])
and check your index.html to you have included all the .js files
change this it will help you
The code you posted is rather irrelevant, the error states clearly what's wrong
the starter.services
is not available at the time application bootstrap
either the services.js
is not loaded (check your network tab in developer tools) or it's loaded in wrong order (most likely)
as soon as module that matches ng-app
is loaded angular will bootstrap the application, so you can reorder the files so services and controllers are loaded before app.js
OR
you can automate with gulp or grunt to concatenate all files you need into one
OR
you could remove the ng-app
from your html and add following lines at the bottom of head or body to manually bootstrap
<script>
angular.element(document).ready(function() {
angular.bootstrap(document, ['starter']);
});
</script>
that way order of the files will not matter
If you ever e across such errors please make sure you've added your js and other resources referred in htmls to index.html file with absolute path.
This an abstract answer to anyone looking for solution to such problems.
Hope this helps.