Trying to setup some helpers value to the module. Tried with service and value and it didn't help:
var finance = angular.module('finance', ['finance.services'])
.value("helpers", {
templatePath: function (name) {
return '/areas/scripts/finance/templates/' + name + '/index.html';
}
})
.config(['$routeProvider', 'helpers', function ($routeProvider, helpers) {
$routeProvider.
when('/', {
templateUrl: helpers.getTemplatePath('dashboard'),
controller: DashboardController
})
.when('/people', {
templateUrl: '/areas/scripts/app/people/index.html',
controller: PeopleController
})
.otherwise({
redirectTo: '/dashboard'
});
}]);
What I am doing wrong?
The problem is that you are trying to inject a value object helpers in the config block of a AngularJS module and this is not allowed. You can only inject constants and providers in the config block.
The AngularJS documentation (section: "Module Loading & Dependencies") gives the insight into this:
A module is a collection of configuration and run blocks which get
applied to the application during the bootstrap process. In its
simplest form the module consist of collection of two kinds of blocks:
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.
Run blocks - get
executed after the injector is created and are used to kickstart the
application. Only instances and constants can be injected into run
blocks. This is to prevent further system configuration during
application run time.
Instead of .value you can use .constant. Then you can use your service in .config part.
Your helper method is called templatePath and you are calling it inside .config as getTemplatePath. Shouldn't it be:
when('/', {
templateUrl: helpers.templatePath('dashboard'),
controller: DashboardController
})
Related
I am basically following a tutorial and wanted to understand why this code works.
This is my service:
app.factory('postFactory', ['$http', function($http){
var obj= {
postList:[]
};
obj.getAll= function(){
return $http.get('/posts').success(function(data){
angular.copy(data, obj.postList);
});
};
return obj;`enter code here`
}]);
This is the resolve:
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'MainCtrl',
resolve: {
posts: function(postFactory){
return postFactory.getAll();
};
)
The resolve calls the method getAll() on postFactory. I know that a resolve is reached in the code before the controller is initialized and therefore, the service. How does it then access the method at all? Also, as stated in this question and answer, AngularJS dependency injection of value inside of module.config,
A module is a collection of configuration and run blocks which get applied to the application during the bootstrap process. In its simplest form the module consist of collection of two kinds of blocks:
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.
So if we want to 'prevent accidental instantiation of services before they have been fully configured', why are we being able to instantiate them in the resolve?
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.
So I have an AngularJS application in which I am attempting to bootstrap only after all of the data for the application is loaded. I need to be able to make the requests in JSONP format so I am attempting to load the $resource module by using a .run statement.
Here's how it looks:
(function(){
// Define our app
app = angular.module("GRT", ["ngResource", "ngRoute"])
.run(function($resource){
console.log($resource);
})
// Configure our route provider and location provider
.config(function($routeProvider, $httpProvider, $locationProvider) {
$routeProvider.
when('/', {
templateUrl: 'views/home.html'
})
.when('/customer-site-registration', {
templateUrl: "views/customer-site-registration.html",
controller: "customerSiteRegistration"
})
.otherwise({
redirectTo: '/'
});
// $locationProvider.html5Mode(true);
});
}())
Basically no matter what I do it wont run that run block. Any ideas?
Run blocks do not run until the Angular application is bootstrapped. I needed this to run before the bootstrapping.
In this setup the ng-app attribute was removed from the enclosing DOM element to prevent auto-bootstrapping and I was doing it manually after running some code.
Since I was only using it to get access to resource, I instead grabbed it manually like this:
var $resource = angular.injector(["ngResource"]).get("$resource");
Hope this helps someone else!
I have an app that uses Angular Translate (https://github.com/PascalPrecht/angular-translate). Translate works great in the application via browser but when I try to test any controller I get Error: Unexpected request: GET locale/locale-en.json. How do I unit test my controllers since translate does a GET request for the language file on startup?
I am using the yeoman angular generator with Karma.
App.js:
angular.module('myApp', ['ngCookies', 'ui.bootstrap', 'pascalprecht.translate'])
.config(function ($routeProvider, $locationProvider, $translateProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.otherwise({
redirectTo: '/'
});
$translateProvider.useStaticFilesLoader({
prefix: 'locale/locale-',
suffix: '.json'
});
$translateProvider.uses('en');
$translateProvider.useLocalStorage();
});
Controller Test:
describe('Controller: DocumentationCtrl', function () {
// load the controller's module
beforeEach(module('myApp'));
var DocumentationCtrl,
scope,
$httpBackend;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope, $injector) {
$httpBackend = $injector.get('$httpBackend');
scope = $rootScope.$new();
DocumentationCtrl = $controller('DocumentationCtrl', {
$scope: scope
});
}));
it('should attach a list of awesomeThings to the scope', function () {
$httpBackend.whenGET('locale/locale-en.json').respond(200, {
"TITLE": 'My App'
});
expect(scope.awesomeThings.length).toBe(3);
});
});
The Documentation Controller is just a standard generated controller.
You have to specify the preferred language within config phase rather then run phase. So $translate.uses('us') becomes $translateProvider.preferredLanguage('us').
Same goes for useLocalStorage(). These are all methods to configure $translate service.
You should also try to avoid uses() to set a default language. Use preferredLanguage() instead. The reason for this is, that $translate.uses() tries to load a i18n file as soon as possible,
if there's a cookie or similar which uses another language key, uses() will load two files, that why we introduced preferredLanguage() And yea, this should solve the problem.
Avoid initialize application level module, put your controllers in myApp.controllers and test this module instead.
"We recommend that you break your application to multiple modules. (...) The reason for this breakup is that in your tests, it is often necessary to ignore the initialization code, which tends to be difficult to test."
http://docs.angularjs.org/guide/module
I think you have a wrong order: The setup for angular-translate tries to loading the language right after calling uses(lang) (after the block, indeed).
We had similar problems when developing the adapters in anguluar-translate. Try to look into https://github.com/PascalPrecht/angular-translate-loader-url/blob/16e559030bce819e8ca1b82fed7163286b57bafe/test/unit/translateUrlLoaderSpec.js which are the tests for the url loader plugin.
Should the controller not be injected a step later?
I am still very new to AngularJS and am working through setting up my first application. I would like to be able to do the following:
angular.module('App.controllers', [])
.controller('home', function () {
$scope.property = true;
}]);
angular.module('App', ['App.controllers'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/', {templateUrl: 'partials/home.html', controller: home});
}]);
Using this setup the following error is generated:
Uncaught ReferenceError: home is not defined from App
My question is: How can I register controllers using angular.module.controller() (or $controllerProvider.register() directly) and use the registered controller elsewhere in my app.
My motivation: I would like to avoid using either global constructor functions as my controllers (as most of the examples on angularjs.org use) or complex namespacing. If I can register and use controllers as single variable names (that are not then put in the global scope) that would be ideal.
Try using a string identifier.
routeProvider.when('/', {templateUrl: 'partials/home.html', controller: 'home'});
When you use a literal, it is looking for a variable called home, but that doesn't exist in this case.
If you are getting controller is not defined error you have to write your controller name within the quotes.
or define your controller like this
function controllerName()
{
//your code here
}
refer this: Uncaught ReferenceError:Controller is not defined in AngularJS