App is breaking due to factory in angularjs. Why? - javascript

I have no idea why this code is breaking...
<!DOCTYPE html>
<html>
<head>
<title>TEST</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"> </script>
<script>
var app = angular.module('test', []);
app.service('mySerivce', function($scope) {
return 0;
});
app.controller('myController', function($scope, myService) {
});
</script>
</head>
<body ng-app='test'>
<div ng-controller="myController">
</div>
</body>
</html>
I am getting the error message:
Error: [$injector:unpr] http://errors.angularjs.org/1.5.6/$injector/unpr?p0=myServiceProvider%20%3C-%20myService%20%3C-%20myController

$scope is not available to factories or services. Also I misspelled myService.

Add controller dependency in string array format, like below:
.controller('MyController', ['myService', function (myService) {
}]);
You can refer this in Error: [$injector:unpr]

Related

Module Exceptions in Angularjs and $exceptionHandler

In the documentation of Angular 1 for $exceptionHandler it says:
Any uncaught exception in angular expressions is delegated to this service.
https://code.angularjs.org/1.3.20/docs/api/ng/service/$exceptionHandler
Yet when I get a module initialisation error (Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to: ...) it does not seem to get logged via the $exceptionHandler.
I want to be able to log these Errors to Sentry via Raven and am having trouble finding a solution to this.
This is an example of what i am trying to achieve:
// Main App module
angular.module('app', ['app.welcome', 'app.contact'])
.factory('$exceptionHandler', [function() {
return function myExceptionHandler(exception, cause) {
// why does the module initialisation error not get caught here..?
console.log("[ERROR] ", exception.message);
};
}]);
// a module I forgot to load..
// app.module('app.contact', []);
// another sub module
angular.
module('app.welcome', [])
.controller('ExampleController', ['$scope', '$window', function($scope, $window) {
$scope.test = function() {
$window.alert('test');
};
}]);
<!doctype html>
<html lang="en" ng-app="app">
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="ExampleController">
<button ng-click="test()">Test</button>
</body>
</html>
Here is a snippet which raise an error because $q is not injected, do whatever you want in custom exception handler.
angular.module('app', []);
angular.
module('app')
.controller('ExampleController', ['$scope', function($scope) {
$scope.test = function() {
$q.when("foo");
};
}])
.factory('$exceptionHandler', [function() {
return function myExceptionHandler(exception, cause) {
console.log("[ERROR] ", exception.message);
};
}]);
<!doctype html>
<html lang="en" ng-app="app">
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="ExampleController">
<button ng-click="test()">Raise Error</button>
</body>
</html>

Defining angular modules in different files

I have 3 js files in my application
(mainApp.js, template.js, app.js)
index.html
<html lang="en" ng-app="myapp">
mainApp.js
var app = angular.module('myapp',
['myapp.templateApp', 'myapp.demoApp']);
template.js
angular.module('myapp.templateApp', ['slick', 'localization'])
.controller('CountryLaunguageSelection', [
'$scope', '$rootScope','$http',
function($scope, $rootScope,$http) {
}
]);
app.js
var app = angular.module('myapp.demoApp', [
'ui.router',
'ui.grid',
'ngTouch',
'ui.grid.selection',
'ui.bootstrap',
'ngTable'
]);
app.config(function($stateProvider, $urlRouterProvider) {
});
I need the 3 modules to be in 3 different files.Could anybody tell me what is wrong with the above code.
I am getting the below error
Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.2.28/$injector/modulerr?p0=app&p1=Error%3A%20…0%2FdemoApp%2Ftemplate%2Fthird-party%2Fangular%2Fangular.min.js%3A18%3A387)
Just created such a localhost - it works. Try to compare your index.html and dependencies.
index.html
<!DOCTYPE html>
<html lang="en" ng-app="myapp">
<head lang="en">
<meta charset="UTF-8">
<script src="angular.min.js"></script>
<script src="mainApp.js"></script>
<script src="app.js"></script>
<script src="template.js"></script>
</head>
<body>
<div ng-controller="CountryLaunguageSelection">
{{data.myData}}
</div>
</body>
</html>
mainApp.js
var app = angular.module('myapp', ['myapp.templateApp', 'myapp.demoApp']);
app.js
var app = angular.module('myapp.demoApp', []);
app.config(function() {
});
template.js
angular.module('myapp.templateApp', [])
.controller('CountryLaunguageSelection', [
'$scope', '$rootScope','$http',
function($scope, $rootScope, $http) {
$scope.data = {
myData: "Hello"
};
}
]);

End-to-End Testing AngularJS app with Jasmine

I have an AngularJS app. I would like to implement some end-to-end testing that I can run on-demand. In an effort to do this, I've built a basic test screen with the following:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test Results</title>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine-html.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/boot.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular-mocks.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.css" />
<!-- Load the Test Files-->
<script type="text/javascript" src="e2e/tests.e2e.js"></script>
</head>
<body>
run tests
</body>
</html>
My tests.e2e.js file looks like the following:
'use strict';
describe('MyApp', function() {
browser.get('http://localhost:11000/index.html');
describe('Welcome Screen', function () {
});
});
When click "run tests" in my test runner, I get an error that says:
MyApp encountered a declaration exception
ReferenceError: browser is not defined
My question is, what am I doing wrong? The examples I've seen use browser to basically start the app. However, I can't seem to figure out how to do end-to-end tests on-demand.
Thank you for any help you can provide.
(function (module) {
var myController = function ($scope, $http) {
$http.get("/api/myData")
.then(function (result) {
$scope.data= result.data;
});
};
module.controller("MyController",
["$scope", "$http", myController]);
}(angular.module("myApp")));
describe("myApp", function () {
beforeEach(module('myApp'));
describe("MyController", function () {
var scope, httpBackend;
beforeEach(inject(function ($rootScope, $controller, $httpBackend, $http) {
scope = $rootScope.$new();
httpBackend = $httpBackend;
httpBackend.when("GET", "/api/myData").respond([{}, {}, {}]);
$controller('MyController', {
$scope: scope,
$http: $http
});
}));
it("should have 3 row", function () {
httpBackend.flush();
expect(scope.data.length).toBe(3);
});
});
});

AngularJS routeprovider injection error

I'm learning AngularJS, and I'm now trying the $routeProvider, but I can't get it to work.
index.html:
<!DOCTYPE html>
<html ng-app="App">
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular-route.min.js"></script>
<script type="text/javascript" src="scripts/controllers.js"></script>
</head>
<body>
<div ng-view></div>
</body>
</html>
view.html:
<p>Hello World!</p>
controllers.js:
var app = angular.module('App', ['ngRoute']);
app.config(
function($routeProvider){
$routeProvider.when("/something",{
templateUrl: "view.html",
controller: "MyController"
})
.otherwhise({
redirectTo: "/"
});
}
);
function MyController($scope){
}
Whenever I run this, I get an error message that says
Uncaught Error: [$injector:modulerr]
How can I solve this?
Change .otherwhise to .otherwise.
A good practice when you run into these issues is to try the un-minified version of Angular.
The un-minified error is much more helpful:
Uncaught Error: [$injector:modulerr] Failed to instantiate module App
due to: TypeError: Object # has no method 'otherwhise'
Solution: Create a $inject property on your route config as follows: -
var app = angular.module('App', ['ngRoute']);
(function (app) {
var routeConfig = function($routeProvider){
$routeProvider.when("/something",{
templateUrl: "view.html",
controller: "MyController"
})
.otherwhise({
redirectTo: "/"
});
};
routeConfig.$inject = ['$routeProvider'];
app.config(routeConfig);
})(angular.module("App"));
AngularJS will now be able to inject $routeProvider successfully when js is minified.

Angularjs app not working after adding new controller

Initially my controller.js looked like this
function MyCtrl1() {}
MyCtrl1.$inject = [];
function MyCtrl2() {
}
MyCtrl2.$inject = [];
And the html code like this
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="utf-8">
<title>My AngularJS App</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
<script src="http://angular-ui.github.com/bootstrap/ui-bootstrap-tpls-0.2.0.js"></script>
<link rel="stylesheet" href="css/app.css"/>
</head>
<body>
<ul class="menu">
<li>view1</li>
<li>view2</li>
</ul>
<div ng-view></div>
<div>Angular seed app: v <span app-version></span></div>
<div>Author is : <span app-author></span></div>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>
<script src="js/directives.js"></script>
</body>
</html>
Here is the service.js code
angular.module('myApp.services', []).
value('version', '0.1')
.value('author','Jay');
And the directive.js code
angular.module('myApp.directives', []).
directive('appVersion', ['version', function(version) {
return function(scope, elm, attrs) {
elm.text(version);
};
}])
.directive('appAuthor', ['author', function(author) {
return function(scope, elm, attrs){
elm.text(author);
};
}]);
The above code worked completely worked fine and displayed version and author configured in service.js
The moment i modify my controller.js to include a new controller as below it stops working and nor the version nor the author is displayed.
The modified controller code is as below
function MyCtrl1() {}
MyCtrl1.$inject = [];
function MyCtrl2() {
}
MyCtrl2.$inject = [];
angular.module('myApp', ['ui.bootstrap']);
var TabsDemoCtrl = function ($scope) {
$scope.panes = [
{ title:"Dynamic Title 1", content:"Dynamic content 1" },
{ title:"Dynamic Title 2", content:"Dynamic content 2" }
];
};
TabsDemoCtrl.$inject = ['$scope'];
Any pointers why this thing is not working.
Looks like your problem is the redeclaration of myApp here:
angular.module('myApp', ['ui.bootstrap']);
I was able to reproduce your problem when I had
angular.module('myApp', ['myApp.services', 'myApp.directives']);
angular.module('myApp', ['ui.bootstrap']);
Switching it to
angular.module('myApp', ['myApp.services', 'myApp.directives', 'ui.bootstrap']);
made everything work again.

Categories