AngularJS: Testing registered controllers with Karma - javascript

I'm fed up with running unit tests with my AngularJS application using Karma an Jasmine. I'm not using requireJS, but custom solution with dynamic loading controllers based on loading widgets segments. Is there any ways to perform a mock or injection of $controllerProvider in some pre-loaded test-helper.js?
My typically controller looks like:
'use strict';
Polygons.app.controllerProvider.register('MyController',
['$scope', '$rootScope', '$location', 'MyService'
function ($scope, $rootScope, $location, MyService) {
...
}
]
);
Polygons.app is concept wich is described in app.js:
Polygons.app = angular.module('app', ['ngRoute', 'ngSanitize', 'ngCookies'])
.config(['$routeProvider', '$httpProvider', '$compileProvider', '$routeSegmentProvider', '$locationProvider', '$controllerProvider', 'router', '$provide',
function ($routeProvider, $httpProvider, $compileProvider, $routeSegmentProvider, $locationProvider, $controllerProvider, router, $provide) {
Polygons.app.controllerProvider = $controllerProvider;
Polygons.app.compileProvider = $compileProvider;
...
Because module.config() doesn't execute during tests there is no way to obtain controllerProvider property of Polygons.app - I'm getting an error 'Cannot read property 'register' of undefined'.
So is there any ways to solve that problem?
Please, any help or conjecture, I'm totally lost.
Thanks a lot.

Related

Laravel mix and AngularJs

I'm trying to use Laravel Mix, which runs webpack, to compile an angular app into one file. I get the error:
Uncaught ReferenceError: app is not defined
my webpack.mix.js:
const { mix } = require('laravel-mix');
mix.js('resources/assets/js/dependencies.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
my bundle.js :
//load angular
require('angular');
//Load Angular's plugins
require('angular-ui-router');
//Init Angular app
require('./app/app');
//Load angular controllers
require('./app/Controller/aboutController');
....
//Load angular directive
require('./app/Directive/directive');
//Load angular services
require('./app/Services/AccountService');
....
My app/app.js:
var app = angular.module('app', ['ui.router']);
app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function ($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'app/View/homeView.html',
controller: 'homeController'
})
...
}]);
app.run(['$state', '$rootScope', function ($state, $rootScope) {
//APP RUN
}]);
I get the Uncaught ReferenceError: app is not defined when I call app.controller(), for example app/Controller/aboutController.js:
app.controller("aboutController", ['$scope', '$rootScope', '$http', function ($scope, $rootScope, $http) {....}
Am i missing something? If i load all the file one by one using html it works fine.
If you are defining your app's controller in separate file , then you cannot use directly app as there is no reference . You first have to refer to the module .
angular.module('app')
.controller('aboutController'....
Let me know if this work for you.
For anyone looking to do this in a more automated way for their next Laravel project, I created an article to explain how. Tested on Angular versions 4-7 with Laravel versions 5.4-5.8. I hope it helps!

Error: ng:areq Bad Argument AngularJS

I am working on a new portfolio site and want to use AngularJS to display my work and pure css to format layout etc.
I found a useful tutorial that outlined how to structure your app for future scaling and have set up a file tree like so:
so each component is a basically a mini MVC. I have set up my routes in app.routes.js and organised app.module.js as below:
app.module.js:
angular.module('app', ['ngRoute', 'appControllers', 'appResources']);
angular.module('appControllers', ['ngRoute']);
angular.module('appResources', ['ngResource']);
app.route.js:
angular.module('app')
.config(['$routeProvider', function ($routeProvider) {
'use strict';
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'app/components/home/home-view.html',
controller : 'HomeCtrl'
})
// route for the about page
.when('/about', {
templateUrl : 'app/components/about/about-view.html',
controller : 'AboutCtrl'
})
// route for the contact page
.when('/contact', {
templateUrl : 'app/components/contact/contact-view.html',
controller : 'ContactCtrl'
});
}]);
so this is my set up, for now, I just need to see that each controller for the routes are working and then I will begin adding in my content, but I have hit a hurdle straight away as the controllers for each view are showing as undefined.
Here is an example of a controller, they are all the same at the moment, but with a different message:
angular.module('appControllers')
.controller('AboutCtrl', ['$scope', '$http', function ($scope, $http) {
'use strict';
$scope.message = 'This will be the about page';
}]);
the html is correct and there are no typos, so I am scratching my head as to why this is showing up as an error.
Is this something to do with the way I have my modules set up?
Any assistance would be greatly appreciated.
Many thanks in advance.
This error is telling you that your HomeCtrl is undefined. You will need to include a <script src="app/components/home/HomeController.js"></script> in your index.html file to include each of your controllers with this type of app configuration.
If you want to avoid this, you can scaffold your app something like this.
(function () {
"use strict";
angular.module('appControllers')
.controller('HomeCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.message = 'This will be the home page';
}])
.controller('AboutCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.message = 'This will be the about page';
}]);
})();
There is no single "best" way to do something. It is all relative to the needs of your app and preference.

Angular 1.4.2 injection of $cookies not working

I have a problem with Angular and injecting $cookies into a controller.
The $cookies is working fine in a service, but with this controller I'm getting an issue.
var app = angular.module('app', [
"ui.router",
"ngCookies",
'ui.bootstrap']);
angular
.module("app")
.controller("ListController", ListController);
ListController.$inject = ['$scope', 'DataService', '$state', "AuthenticationService", "$cookies"];
function ListController($scope, DataService, $state, AuthenticationService, $cookies) {
....
}
The $cookies object is coming through as undefined. The angular-cookies.js is included on the page, and is working inside the included AuthenticationService.
I found my problem:
Someone had cut and pasted the original controller code into a new controller, but neglected to rename the controller on the line:
ListController.$inject =[...];
So, when I came along and added the $cookies parameter, my version was being overridden.
Try this way
var app = angular.module('app', [
"ui.router",
"ngCookies",
'ui.bootstrap']);
angular
.module("app")
.controller("ListController",['$scope', 'DataService', '$state', "AuthenticationService", "$cookies", function ($scope, DataService, $state, AuthenticationService, $cookies) {
....
}]);
Did you include the file angular-cookies[.min].js ?
Also, as a good practice, don't use the same module for the app and the controllers. Have a
angular.module('app', [ 'app.controllers']);
angular.module('app.controllers', [
\\ define each controller here
]);
defined so that you can have clean separation of them.
Are $scope, DateService, $state available in your controller? I usually put this line of code after the declaration of controller
angular
.module("app")
.controller("ListController", ListController);

Angular JS adding an extra module causes project to not render any pages

Sorry if this is a noob question but I am brand new to Angular JS.
While programming my web app I wanted to add an extra page to my website. Currently I have a main module that contains smaller modules for each webpage:
'use strict';
angular.module('myApp', [
'ngRoute',
'myApp.view1',
'myApp.view2',
'myApp.version',
'ui.bootstrap'
]).
config(['$routeProvider', function($routeProvider) {
$routeProvider.otherwise({redirectTo: '/view1'});
}]);
This works fine but when I try and add an extra module 'myApp.view3' none of the pages render. Here is what the modules look like:
view1
angular.module('myApp.view1', ['ngRoute'])
// configuration
.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.when('/view1', {
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl'
});
}])//controller and factory not shown
view 3
angular.module('myApp.view3', ['ngRoute'])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/view3', {
templateUrl: 'view3/view3.html',
controller: 'View3Ctrl'
});
}])
.controller('View3Ctrl', ['$scope', function($scope){
}
]);
Sorry I just realized I had forgot to include the JS script within the HTML file

Adding Bootstrap UI Module to angularjs project

I'm trying to add the bootstrap-ui module to my angular.js project. The documentation states that I simply have to add
angular.module('myModule', ['ui.bootstrap']);
to get this working. But I can't find out how I would add this in any way. I've read the whole chapter of https://docs.angularjs.org/guide/module and read lots of threads about it, but everything I tested didn't work so far.
my app.js:
angular.module('MyApp', ['ngCookies', 'ngResource', 'ngMessages', 'ngRoute', 'mgcrea.ngStrap'])
.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
// followed by my routing
myCtrl
angular.module('MyApp')
.controller('MyCtrl', ['$scope', '$location', '$rootScope', '$routeParams', '$resource', '$alert', 'MyService',
function ($scope, $location, $rootScope, $routeParams, $resource, $alert, MyService) {
what I tried:
adding 'ui.bootstrap' after 'mgcrea.ngStrap' in app.js
adding 'ui.bootstrap' after *'MyService' in myCtrl
many more similar variations
The error messages I get depend on what I did. Since I'm probably completely on the wrong path at the moment I was hoping someone could tell me how I can add a module in angular.js correctly?
edit some error messages I encountered:
When I start my Crtl code with:
angular.module('MyApp', ['ui.bootstrap'])
I get
[ng:areq] Argument 'NavbarCtrl' is not a function, got undefined
(navbarctrl is a completely different ctrl)
when I start my app.js with
angular.module('MyApp', ['ngCookies', 'ngResource', 'ngMessages', 'ngRoute', 'mgcrea.ngStrap', 'ui.bootstrap'])
I get
TypeError: object is not a function
In my AuthService I try to use $alert (this works without bootstrap-ui) like
$alert({
title: 'Success!', //...
**edit 2: ** the problem seems to be that I can only use ngStrp OR ui.bootstrap (both use bootstrap underneath)
Are you ensuring that Angular UI specific JS Files are sent from server to client through bundling or direct reference?
You have to inject dependency of module in your app: something like this angular.module('MyApp', ['ui.bootstrap']);

Categories

Resources