I started my first angular application, and am running into an issue where my "home" module isn't working because of a dependency issue. I don't see any dependency missing that I would need. I am using $stateProvider, and $urlProvider, but I am injecting that into the configuration for the home module, so I'm not sure where the problem would lie ?
Config.$inject = ["$stateProvider", "$urlRouterProvider"];
angular.module('home', []).config(Config)
function Config($stateProvider, $urlRouterProvider){
$stateProvider
.state('home', {
url: '/login',
templateUrl: './views/login.html'
})
}
angular.module('home').controller('loginCtrl', function($scope){
$scope.helloWorld = function(){
console.log("This works!")
}
})
The consoled error:
[$injector:modulerr] http://errors.angularjs.org/1.5.5/$injector/modulerr?p0=home&p1=Error%3A%20…
Since "$stateProvider" and "$urlRouterProvider" providers are not part of the core AngularJS module, you need to inject modules, that have this provides into your home module definition. As far as I know, $stateProvider is from ui router module, so
angular.module('home', ['ui.router']).
...
Keep in mind that you also need to include this Javascript in your HTML file. It is in the angular-ui-router file
<script src="js/angular-ui-router.min.js"></script>
Related
I'm writing an Ionic app, which uses AngularUI's Router. I'd like to query localstorage using a factory I wrote, so I can determine whether to show a first-run screen or not.
My index.html loads scripts in this order:
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
<script src="js/routes.js"></script>
<script src="js/directives.js"></script>
<script src="js/filters.js"></script>
And my routes config looks like this (truncated for brevity):
angular.module('app.routes', [])
.config(function($stateProvider, $urlRouterProvider, storageFactory) {
$stateProvider
.state('myApp.mainscreen', {
url: '/main',
views: {
'side-menu21': {
templateUrl: 'templates/main.html',
controller: 'mainCtrl'
}
}
})
// ...
$urlRouterProvider.otherwise('/menu/main')
Now I have a module called app.services, which contains my factory, storageFactory (I know, I'm going to move it out of the services module ;)). When I attempt to inject storageFactory like so:
angular.module('app.routes', ['app.services', 'storageFactory'])
.config(function($stateProvider, $urlRouterProvider, storageFactory) {
I get an error similar to this:
Error: [$injector:nomod] Module 'storageFactory' 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.
I'm certain that my app has loaded app.services and storageFactory prior to loading, but I just can't seem to get it to work correctly.
How can I resolve this?
You can inject factories in UI router resolve blocks, without injecting them in the config block since it can only be injected with providers. For example:
$stateProvider
.state('myApp.mainscreen', {
url: '/main',
views: {
'side-menu21': {
templateUrl: 'templates/main.html',
controller: 'mainCtrl'
}
},
resolve: {
firstRun: ['storageFactory', function(storageFactory) {
// Do what you want with storageFactory here!
// Full infos here: https://github.com/angular-ui/ui-router/wiki#resolve
}]
}
})
you cant inject services in config only provides but you can do it in app.run Here's the calling order:
app.config() //only provides can be injected
app.run()
directive's compile functions (if they are found in the dom)
app.controller()
directive's link functions (again, if found)
in your case you can also use route resolve property
I have a Rails app which has some complex routing. My Angular application exists in a deep URL such as /quizzes/1
I was hoping to do this the Angular was by injecting $window into my routes configuration and then sniffing $window.location.pathName. This does not seem possible as the application throws an "Unknown provider: $window from myApp" at this stage.
Is there a best-practice way to handle this with Angular? The reason I would like to do this is to use HTML5 mode while the app lives in a deep directory.
Here's an example of what I was hoping for, http://jsfiddle.net/UwhWN/. I realize that I can use window.location.pathname at this point in the program if it's the only option.
HTML:
<div ng-app="myApp"></div>
JS:
var app = angular.module('myApp', [])
app.config([
'$window', '$routeProvider', '$locationProvider',
function($window, $routeProvider, $locationProvider) {
var path = $window.location.pathname
// Coming Soon
// $locationProvider.html5Mode(true)
$routeProvider
.when(path + '/start', {
controller: 'splashScreenController',
templateUrl: 'partials/splash-screen.html'
})
.when(path + '/question/:id', {
controller: 'questionController',
templateUrl: 'partials/question-loader.html'
})
.otherwise({
redirectTo: path + '/start'
})
}])
Only constants and providers can be injected into config block. $window isn't injectable into your config block because $window is a service.
From Angular docs:
Configuration blocks - get executed during the provider registrations and configuration phase. Only providers and constants can be injected into configuration blocks. This is to prevent accidental instantiation of services before they have been fully configured.
And, you don't need $window service there anyway. Just use <base> tag:
<base href="/quizzes/1/" />
and keep your routes relative to it.
I'm trying to use the angular ui router with storm path for angular, but I keep getting an unknown provider error. My code is as follows,
var angular = require("angular");
// app.js
var app = angular.module('app', [require('angular-ui-router'), require("stormpath-sdk-angularjs")]);
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'partials/home.html'
})
.state('about', {
url: '/about',
templateUrl: 'partials/about.html'
});
})
.run(function($stormpath){
$stormpath.uiRouter({
loginState: 'login',
defaultPostLoginState: 'home'
});
});
And here is the error page,Error: $injector:unpr
Unknown Provider
This was a bug stormpath-sdk-angularjs and has been fixed in version 0.8.2.
To get it to work with browserify, please add these lines to your package.json:
"browser": {
"stormpath": "./node_modules/stormpath-sdk-angularjs/dist/stormpath-sdk-angularjs.js",
"stormpath.templates": "./node_modules/stormpath-sdk-angularjs/dist/stormpath-sdk-angularjs.tpls.js"
}
And then require it like:
var angular = require("angular");
var app = angular.module('app', [
require('angular-ui-router'),
require('stormpath'),
require('stormpath.templates')
]);
Stormpath are using the wrong module name in their module.exports (I've raised a bug here ~ https://github.com/stormpath/stormpath-sdk-angularjs/issues/80).
For now, you can do this
var angular = require("angular");
require('stormpath-sdk-angularjs');
// app.js
var app = angular.module('app', [
require('angular-ui-router'), // this one is fine
'stormpath',
'stormpath.templates'
]);
Generally you do not use the require() in the angular dependency list in this way. Rather you need:
var app = angular.module('app', ['ui-router','stormpath']);
Make sure that both libraries are properly included.
The previous answer is likely part of the solution. Perhaps you are using a tool to compile your application such as WebPack? That information would be useful. Please note that the Stormpath Angular SDK provides two modules in the Angular namespace, stormpath and stormpath.templates. If using browserify, you may need to use require('dist/stormpath-sdk-angularjs.js')
P.S. I work at Stormpath, please feel free to reach us via support#stormpath.com if you would like to privately share your code with us. Thanks!
As it turns out the stormpath sdk injects itself into angular. The solution is to load the library after angular.
var angular = require("angular");
var stormpath = require("stormpath-sdk-angularjs");
var app = angular.module('app', [require('angular-ui-router'), "stormpath", "stormpath.templates"]);
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
//States Here
})
.run(function($stormpath){
$stormpath.uiRouter({
loginState: 'login',
defaultPostLoginState: 'home'
});
});
Here is my code:
var app = angular.module('todoApp', ['ui.router', 'ngResource', 'ui.bootstrap']);
app.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state('home', {
url: "/",
templateUrl: '/templates/index.html',
})
.state('signup', {
url: "/signup",
templateUrl: '',
})
}
]);
module.exports = app;
When i'm running in in browser, it show me an error:
ReferenceError: module is not defined
What i'm doing wrong ? How to properly define module ?
The console error message a few lines below the module is not defined gives a hint where the problem is:
Module 'ui.router' is not available! You either misspelled the module name or forgot to load it.
Check if you have included the file containing ui.router into your page (i.e. HTML template) so that Angular can load it.
Add the references to ui-router and bootstrap to make it work.
here is the working app
I realise there are a few answers to this question on here, but I just can't seem to get them working with my set up. This is a Plunker of what I am trying achieve (not my own work): http://plnkr.co/edit/Ofq7Md8udEnIhAPF1NgL?p=preview
Currently, I have this for my index.html file:
<body ng-app="HomeCourtArenaApp">
<div class="container" ng-view></div>
<script src="components/angular/angular.js"></script>
<script src="components/require/require.js"></script>
<script src="components/angular/angular-resource.js"></script>
<script src="scripts/services/data.js"></script>
<script src="scripts/app.js"></script>
</body>
To register the components, I have defined them in the karma.conf.js file:
files = [
JASMINE,
JASMINE_ADAPTER,
'app/components/angular/angular.js',
'app/components/angular/angular-resource.js',
'app/components/angular-mocks/angular-mocks.js',
'app/scripts/*.js',
'app/scripts/**/*.js',
'test/mock/**/*.js',
'test/spec/**/*.js'
];
To then create the service, I use the same technique that seems to be documented online in most examples:
'use strict';
angular.module('jsonData', ['ngResource'])
.factory('jsonData', function($resource) {
return $resource('data/shoe3Dconfig.js');
});
Where an error seems to be triggered is when I try to define the service in my 'app' variable, where adding the service name stops the content loading ['jsonData']:
'use strict';
var app = angular.module('HomeCourtArenaApp', ['jsonData']);
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.otherwise({
redirectTo: '/'
});
});
I would share my views and controllers also, but before I can even use the JSON data in my template, there are an unearthly amount of errors to deal with:
Uncaught Error: Module name "path" has not been loaded yet for context: _. Use require([])
Uncaught Error: Mismatched anonymous define() module: function () {
return getStyleProperty;
}
Uncaught Error: No module: ngResource
There are some other errors also, but these seem to be mainly because the scripts further up the DOM are stopping them loading correctly. Any help would be great!
you could try this :
the app.js:
angular.module('HomeCourtArenaApp', ['HomeCourtArenaApp.services', 'HomeCourtArenaApp.controllers']).
config(['$routeProvider', ($routeProvider) {
$routeProvider.when('/', { templateUrl: 'views/main.html', controller: 'MainCtrl' });
$routeProvider.otherwise({ redirectTo: '/'});
}]);
angular.module('HomeCourtArenaApp.services', ['ngResource']).
factory('JsonData', function($resource){
return $resource('data/shoe3Dconfig.js');
});
angular.module('HomeCourtArenaApp.controllers', []).
controller('MainCtrl', ['$scope', 'JsonData', function($scope, JsonData) {
$scope.objs = JsonData.query();
console.log(objs);
}
}]);
and this is not necessary to load the datas in the html
<script src="scripts/services/data.js"></script>
This edited plunker http://plnkr.co/edit/33qW5VRnQVrHWFlp16kz?p=preview should get you further along the way.
You need to specify the module (jsonData) that you want in your app as a dependency. There is currently no name displayed since your data does not have a name property.
Your JSON service module definition named as 'jsonData'
angular.module('jsonData', ['ngResource'])
This module defines a service provider (factory) 'jsonService'
.factory('jsonService', function($resource) {
You list the 'jsonData' module as a dependency for your module so that you can access anything defined in there
var app = angular.module('plunker', ['jsonData']);
You then use Angular's Dependency Injection to request an instance of jsonService
app.controller('MainCtrl', function($scope, jsonService) {
Note that if you "production-ise" this and minify your JS, you will need to configure the DI code. I will leave that to you to find in the Angular docs.
Does this explain things a bit more?
And you can get the console in plunker by opening the developer tools in your browser.