I have just started with AngularJS
The following code gives an error in the console.
Unknown provider: $scopeProvider <- $scope <- newActiveOrdersModel . I have researched but it looks like Unknown Provider error can happen for a variety of reasons.It would be nice if anyone could point out where I am going wrong ?
var app;
(function(angular){
app = angular.module('OrdersDashboard',[]);
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/current/new', {templateUrl: 'orders/partials/new_current', controller: 'newActiveOrdersCtrl'}).
otherwise({redirectTo: '/'});
}]);
app.service('newActiveOrdersModel', ['$scope', '$rootScope',
function($scope, $rootScope){
this.Orders=["This is a test order"];
this.fetchOrders = function(){
console.log("This is a test order");
this.Orders=["This is a test order1111"];
};
}]);
app.controller('newActiveOrdersCtrl', ['$scope', '$rootScope', 'newActiveOrdersModel',
function($scope, $rootScope, newActiveOrdersModel){
$scope.test="Hello World";
}]);
})(angular);
It seems like Angular Js cannot recognize "newActiveOrdersModel".
This just a guess but I don't know why you have $scope listed as a dependency of your service. I think something like this
app.service('newActiveOrdersModel', ['$rootScope',
function($rootScope){..}]
will solve the error. Also I wouldn't include $rootScope unless you absolutely need it. It's generally considered bad practice in Angular to store stuff in the $rootScope.
Related
In AngularJS, we use an array to pass the services as arguments to the controller function so that they keep their functionality after minification. for example:
myApp.controller('mycontroller', [$scope, $log, function($scope, $log){
$scope.name = 'Jimmy';
$log($scope.name);
}]);
But when you inject a dependency to the .config method, you don't have to use an array. For example:
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function($routeProvider){
$routeProvider
.when('/', {
templateURL: 'pages/main.html',
controller: 'myController'
})
});
I'm having a hard time understanding dependency injection in AngularJS. I thought I understood it but I guess I don't. Wouldn't the variable name $routeProvider be minified and lose it's functionality as a service, the same as when you use dependency injection (without an array) with a controller?
I'm working on debug step. There are several pages. Each time, I would need console the $rootScope for debug. I want to know if there is a way to console log the $rootScope for all controller? In other words, How can I console $rootScope before each controller in angular?
Update:
I mean the statement should run before all controllers without modify the controllers.
If you are using angular routing, you can use:
angular.module('myModule').run([ '$rootScope', function($rootScope) {
$rootScope.$on("$locationChangeStart", function() {
console.log($rootScope);
});
} ]);
And if you re using ng-view you can instead listen for $viewContentLoaded
Before execute route change locationChangeStart, still if you want to console it, then you can console or initialize it from main controller first.
var app = angular.module('app', ['ngRoute']);
app.controller('MainController', ['$scope', '$rootScope', 'myServices', function ($scope, $rootScope, myServices) {
$rootScope.test = 'Hello World';
console.log($rootScope.test);
}]);
I am using the generator-angular-fullstack for my app and have come into a problem when minifying / uglyfying my code.
Before minifying my code i could use services and they would work fine but afterwards i get the following error:
[$injector:unpr] Unknown provider: aProvider <- a
I read that i need to add inline annotations to my controller like this (to stop the minify process from destroying the service:
app.controller('mainController', ['$scope', '$http', function($scope, $http) {
$scope.message = 'HOORAY!';
}]);
generator-angular-fullstack creates controllers like this:
(function () {
class EmployeesearchComponent {
constructor($scope, $rootScope, $state, $stateParams, elasticservice, $mdDialog) {
$scope.message = 'HOORAY!';
};
}
angular.module('myApp')
.component('employeesearch', {
templateUrl: 'app/employeesearch/employeesearch.html',
controller: EmployeesearchComponent
});
})();
Where am i supposed to add the services as strings?
Thanks,
I needed to add the strings above the constructor field:
static $inject = ['$scope', '$http']
Another solution is to change the controller key to have an array with the parameters' names and the controller class at the end, like so:
[...]
.component('employeesearch', {
controller: ['$scope', '$rootScope', '$state', '$stateParams', 'elasticservice', '$mdDialog', EmployeesearchComponent]
});
But you should really think about adding these annotations during your build process, it would make you code cleaner. If you're using build systems like gulp or grunt there are libraries that allow you to do this just by adding a single extra line to your build script. You can find it as "ng-annotate".
I'm just about to write tests for my angularjs-app. However when Im trying to run the test which is very simpel one i get the following error.
Error: [ng:areq] Argument 'MyPageController' is not a function, got undefined
I'll provide code for the setup of my controllers, config etc.
Route
var myPageApp = angular.module('myPageApp', ['ngRoute', 'ngAnimate', 'ngSanitize', 'app.controller', 'app.service', 'app.filter', 'app.config'])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'App_AngularJs/partials/myPage/myPage.htm',
controller: 'MyPageController',
reloadOnSearch: false,
});
}]);
Controller
var myPageApp = angular.module('app.controller', ['oci.treeview', 'ui.bootstrap'])
.controller('MyPageController', ['$scope', '$routeParams', '$location', '$timeout', '$filter', '$modal', 'myPageService',
function ($scope, $routeParams, $location, $timeout, $filter, $modal, myPageService) {
init();
function init() {
$scope.page = { value: $routeParams.page || 1 };
}
}]);
Simpel test
'use strict';
describe('Testing MyPageController', function(){
var scope;
//mock Application to allow us to inject our own dependencies
beforeEach(angular.mock.module('myPageApp'));
//mock the controller for the same reason and include $rootScope and $controller
beforeEach(angular.mock.inject(function($rootScope, $controller){
//create an empty scope
scope = $rootScope.$new();
//declare the controller and inject our empty scope
$controller('MyPageController', { $scope: scope });
}));
// tests start here
it('should map routes to controllers', function () {
module('myPageApp');
inject(function ($route) {
expect($route.routes['/'].controller).toBe('MyPageController');
expect($route.routes['/'].templateUrl).
toEqual('App_AngularJs/partials/myPage/myPage.htm');
});
});
it('should have variable assigned = "1"', function(){
expect(scope.page.value).toBe(1);
});
});
My wildest and best guess is that i need to mock app.controller but how? Everything starts out with myPageApp which holds references to service, controller etc etc..
I think your issue is that routing and the controller are trying to load different modules viz "myPageApp" and "app.controller" and in your test with beforeEach you are trying to load 'myPageApp' module to which router is associated but not the controller.
So it seems to me that either you use same module for both router and controllers. Or try loading both modules in the test. Still I believe associating the router and controller with same module makes more sense.
An small example as below. Extract the application module in common js file (may be call it app.js)
var myApp = angular.module(
'myApp');
Now define router as
myApp.config(function ($routeProvider) {
$routeProvider
.when('/testUrl', {
templateUrl: '/myApp/views/test-view',
controller: 'TestViewController'
})
Similary define controller as
myApp.controller('TestViewController',[your dependencies goes here])
And now in your tests
beforeEach(module('myApp'));
This will work for sure. Hope it helps.
This code gives me Error: [$injector:unpr] Unknown provider: $scope, $locationProvider <- $scope, $location.
var app = angular.module('myApp.controllers', []);
app.controller('Signup', ['$scope, $location', function($scope, $location) {
$scope.checkEmailValid = function(){
//TODO make a decision about whether to go somewhere, if true do this:
$location.path('/view2');
};
}]);
Am I missing something about how to inject the location service?
I haven't configured $locationProvider, but doing so doesn't seem to help.
You forgot the quotes around $scope and $location :
var app = angular.module('myApp.controllers', []);
app.controller('Signup', ['$scope', '$location', function($scope, $location) {
$scope.checkEmailValid = function(){
//TODO make a decision about whether to go somewhere, if true do this:
$location.path('/view2');
};
}]);
This should to the trick !
Try simpler form (without array form - probably missing quote is your problem):
app.controller('Signup', function($scope, $location) {
$scope.checkEmailValid = function(){
//TODO make a decision about whether to go somewhere, if true do this:
$location.path('/view2');
};
});
Minification can be solved in build time using ngMin and this form is less error prone and more readable