passing variables into angular-ui modal - javascript

I'm having some issues transferring the modal example from the angular-ui documentation here: https://angular-ui.github.io/bootstrap/#/getting_started
I keep running into this error:
Argument 'ModalInstanceCtrl' is not a function, got undefined
controller:
(function () {
'use strict';
angular
.module('projMgrApp')
.controller('forumController', forumController)
forumController.$inject = ['$scope', '$window', '$uibModal', 'Notices'];
function forumController($scope, $window, $uibModal, Notices) {
$scope.Notices = Notices.query();
$scope.successText = "Temp Success Message";
$scope.MessageTitle = "Temp Msg Title";
$scope.MessageText = "Temp Msg Text";
angular.module('projMgrApp').controller('ModalInstanceCtrl', function ($scope, $uibModalInstance, MessageText, messageTitle) {
$scope.MessageText = MessageText;
$scope.MessageTitle = MessageTitle;
$scope.ok = function () {
$uibModalInstance.close();
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
});
$scope.OnAddNoticeClick = function () {
var EditNoticeModal = $uibModal.open({
templateUrl: 'add-edit-modal.html',
controller: 'ModalInstanceCtrl',
resolve: {
MessageText: function () { return $scope.MessageText },
MessageTitle: function () { return $scope.MessageTitle }
}
});
};
}
})();
the modal is spawned from a ui button that runs the OnAddNoticeClick fn.

I managed to get it to work by switching the style of controller to:
angular.module('projMgrApp')
.controller('ModalInstanceCtrl', ModalInstanceCtrl);
ModalInstanceCtrl.$inject = ['$scope', '$uibModalInstance', 'MessageText', 'MessageTitle'];
function ModalInstanceCtrl($scope, $uibModalInstance, MessageText, MessageTitle) {
$scope.MessageText = MessageText;
$scope.MessageTitle = MessageTitle;
$scope.ok = function () {
$uibModalInstance.close();
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
};

Related

scope method in AngularJS directive is not a function, when unit testing

I have this Mocha test:
'use strict';
///////////////////////////////////
describe('all admin page directives', function () {
let scope, $compile, element, tmp;
beforeEach(module('app'));
beforeEach(module('templates'));
afterEach(function () {
scope.$destroy();
});
describe('category', function () {
beforeEach(inject(function ($injector) {
$compile = $injector.get('$compile');
var $rootScope = $injector.get('$rootScope');
scope = $rootScope.$new();
scope.rightSidebarData = {};
$compile('<create-category right-sidebar-data="rightSidebarData"></create-category>')(scope);
return scope.$digest();
}));
it('should do something', function () {
scope.updateModel(); // <<<<<< ERROR HERE
});
});
});
here is my directive:
/* globals angular */
angular.module('app').directive('createCategory',
['UserService', 'AssignmentService', 'NotificationService', 'USER', 'UserInfoService', 'AlertService', '$window',
function (UserService, AssignmentService, NotificationService, USER, UserInfoService, AlertService, $window) {
return {
scope: {
rightSidebarData: '=',
},
restrict: 'EA',
templateUrl: "pages/admin/views/templates/category/create-category.html",
link: function ($scope, el, attrs) {
$scope.rightSidebarData.setOrReset = function () {
$scope.setOrReset();
};
},
controller: function ($scope, FUNCTIONAL_TEAM_ENUM, CATEGORY_ENUM, CategoryService) {
const rsd = $scope.rsd = $scope.rightSidebarData;
$scope.setOrReset = function () {...};
$scope.updateModel = function () {...};
$scope.saveModel = function () {...};
},
};
}
]);
I am getting this error:
TypeError: scope.updateModel is not a function
Does anyone know what I need to do in my test to fix this?
Also, how do I know if I need to use $rootScope.$new() or if I should be passing the parent controller's scope?
I had to add another preprocessor in my karma config file:
preprocessors: {
'./public/pages/**/views/**/*.html':['ng-html2js'], // this
},
and then using the following, it worked:
'use strict';
describe('all admin page directives', function () {
let scope, el, tmp, isoScope;
beforeEach(module('app'));
beforeEach(module('ngMockE2E'));
beforeEach(module('templates'));
afterEach(function () {
scope.$destroy();
});
describe('category', function () {
beforeEach(inject(function ($injector) {
const $compile = $injector.get('$compile');
const $rootScope = $injector.get('$rootScope');
const $templateCache = $injector.get('$templateCache');
console.log('create category template =>', $templateCache.get('pages/admin/views/templates/category/create-category.html'));
scope = $rootScope.$new();
scope.rightSidebarData = {};
scope.rightSidebarData.model = {};
let element = angular.element(`<create-category right-sidebar-data="rightSidebarData"></create-category>`);
el = $compile(element)(scope);
$rootScope.$digest();
scope.$digest();
el.isolateScope().setOrReset();
}));
it('should do something', function () {
el.isolateScope().updateModel();
});
});
});

Unit-testing $timeout execution inside an async call

I'm trying to unit-test a piece of my code contained inside an async call, like this:
function init() {
asyncFunc().then(function (data) {
$timeout(function () {
$scope.isInside = true;
});
});
}
The whole code:
(function (angular) {
// Create module
var myApp = angular.module('myApp', []);
// Controller which counts changes to its "name" member
myApp.controller('MyCtrl', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {
$scope.isInside = false;
init();
function init() {
asyncFunc().then(function (data) {
$timeout(function () {
$scope.isInside = true;
});
});
}
function asyncFunc() {
return new Promise((resolve, reject) => {
$http.get('https://httpbin.org/get').success((data) => {
resolve(data);
}).error((error) => {
reject(error);
});
});
}
}]);
})(angular);
My intention is to test the $scope.isInside value. This is my test:
describe('myApp', function () {
var scope,
controller;
beforeEach(function () {
module('myApp');
});
describe('MyCtrl', function () {
var $httpBackend, endpointCall, $timeout;
beforeEach(inject(function ($rootScope, $controller, _$httpBackend_, _$timeout_) {
$httpBackend = _$httpBackend_;
$timeout = _$timeout_;
endpointCall = $httpBackend.expect('GET', 'https://httpbin.org/get').respond({data: 'data'});
scope = $rootScope.$new();
controller = $controller('MyCtrl', {
'$scope': scope
});
}));
it('initializes', function () {
$httpBackend.flush();
$timeout.flush();
expect(scope.isInside).toBe(true);
});
});
});
The test is failing, the value is "false", but I'm expecting to see a "true" there.
JSFiddle here: http://jsfiddle.net/KarmaCop213/tj6akcyk/1/

AngularJS new value does not arrive in directive

I have the following directive riding a modal. File: login.component.js
(function() {
'use strict';
var app = angular.module('myapp');
app.directive('loginComponent', ['loginService', function(loginService){
return {
templateUrl: 'app/components/login/login.html',
restrict: 'E',
replace: true,
controller: 'homeCrotroller',
link: function ($scope) {
$scope.submit = function() {
$scope.login();
$("#modal-login").modal('hide');
};
$scope.cancel = function() {
$scope.loggingIn = false;
$("#modal-login").modal('hide');
};
$scope.$watch('loggingIn', function() {
if ($scope.loggingIn) {
$("#modal-login").modal('show');
};
});
}
};
}]);
})();
And the next controller. File: home.controller.js
(function() {
'use strict';
var app = angular.module('myapp');
app.controller('homeCrotroller', ['$scope', function($scope){
$scope.loggedIn = false;
$scope.loggingIn = false;
$scope.showLogin = function () {
$scope.loggingIn = true;
};
$scope.logout = function () {
$scope.user = null;
$scope.loggedIn = false;
};
$scope.login = function () {
$scope.loggingIn = false;
$scope.loggedIn = true;
};
}]);
})();
And in my view I call showLogin()
<a class="login" id="btn-login" href="javascript:void(0);" ng-click="showLogin()" title="Entrar">Entrar</a>
This function changes the value of $scope.logging In to true, only this value is not reaching policy. Only reaches the first status (loading screen) that is false

how do we do a unit test a function in an angularJS controller

here is the code:
(function(){
"use strict";
angular.module("dataModule")
.controller("panelController", ["$scope", "$state", "$timeout", "$modal", panelController]);
function panelController($scope, $state, $timeout, $modal){
$scope.property = "panelController";
//how do we do unit test on openCancelWarning.
//i did not find a way to get openCancelWarning function in Jasmine.
function openCancelWarning () {
var cancelModal = $modal.open({
animation: true,
backdrop: "static",
templateUrl: "pages/data/cancel-warning.html",
controller: "cancelWarningController",
size: "sm",
resolve: {
items : function() {
return {
warningTitle : "Are you Sure?",
warningMessage: "There are unsaved changes on this page. are you sure you want to navigate away from this page?Click OK to continue or Cancel to stay on this page"
};
}
}
});
return cancelModal;
}
var resultPromise = openCancelWarning();
var result;
resultPromise.result.then(function(response){
result = response;
});
}
angular.module("dataModule")
.controller("cancelWarningController", ["$scope", "$modalInstance", "items", cancelWarningController]);
function cancelWarningController($scope, $modalInstance, items){
$scope.warningTitle = items.warningTitle;
$scope.warningMessage = items.warningMessage;
$scope.cancel = function() {
$modalInstance.close(false);
};
$scope.ok = function() {
$modalInstance.close(true);
};
}
}());
here is my jasmine unit test code.
describe("Controller: panelController", function () {
beforeEach(module("dataModule"));
var panelController, scope;
var fakeModal = {
result : {
then: function(confirmCallback) {
this.confirmCallback = confirmCallback;
}
},
close: function(confirmResult) {
this.result.confirmCallback(confirmResult);
}
};
beforeEach(inject(function($modal) {
spyOn($modal, "open").andReturn(fakeModal);
}));
beforeEach(inject(function ($controller, $rootScope, _$modal_) {
scope = $rootScope.$new();
panelController = $controller("panelController", {
$scope: scope,
$modal: _$modal_
});
}));
it('test should be true', function () {
var test;
var testResult = panelController.openCancelWarning();
testResult.close(true);
testResult.then(function(response){
test=response;
});
expect(test).toBe(true);
});
});
i wrote above unit test code with the help from Mocking $modal in AngularJS unit tests
i always get below error.
TypeError: 'undefined' is not a function (evaluating 'panelController.openCancelWarning()')
could anyone help this?

how to have to modal with angularjs

I've tried this plunker
http://plnkr.co/edit/s902hdUIjKJo0h6u6k0l?p=preview
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $modalInstance, items) {
but it gives an error
Error: [$injector:unpr] Unknown provider: itemsProvider <- items
I want to have two buttons with 2 differents modal
There are lot of syntax mistakes:
Updated plunker http://plnkr.co/edit/vgM5PLyVgluOeikGvVSA?p=preview
Changes made in JS:-
angular.module('ui.bootstrap.demo', ['ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope, $modal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function (size) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
});
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl2', function ($scope, $modal, $log) {
$scope.items2 = ['item12', 'item22', 'item32'];
$scope.open = function (size) {
var modalInstance2 = $modal.open({
templateUrl: 'myModalContent2.html',
controller: 'ModalInstanceCtrl2',
size: size,
resolve: {
items2: function () {
return $scope.items2;
}
}
});
modalInstance2.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
});
// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $modalInstance, items) {
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl2', function ($scope, $modalInstance, items2) {
$scope.items2 = items2;
$scope.selected = {
item: $scope.items2[0]
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item2);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
You can try my Angular Dialog Service, its built on top of ui.bootstrap's modal but offers prefabricated modals for errors, notifications, progression, confirmations and custom dialogs. It allows you to set configuration as well in your application's config function using 'dialogsProvider' so you don't have to setup keyboard and backdrop settings everytime. There's also support for using angular-translate and fontAwesome.
You can find it here: https://github.com/m-e-conroy/angular-dialog-service
or on bower.io.

Categories

Resources