How to show ionicModal on AngularJS app start? - angularjs

How can I show ionicModal on app start? This code doesn't work
angular.module('testApp', ['ionic'])
.controller('MyController', function($scope, $ionicModal, $ionicPlatform) {
$ionicPlatform.ready(function(){
$scope.initApp = function() {
// some init variables here
if (someVariable){
$scope.openModal();
}
}
// init ionicModal here
$scope.openModal = function() {
$scope.modal.show();
};
$scope.initApp();
});
});
but this work
angular.module('testApp', ['ionic'])
.controller('MyController', function($scope, $ionicModal, $ionicPlatform, $timeout) {
$ionicPlatform.ready(function(){
$scope.initApp = function() {
// some init variables here
if (someVariable){
$timeout(function() {
$scope.openModal();
}, 1000);
}
}
// init Modal here
$scope.openModal = function() {
$scope.modal.show();
};
$scope.initApp();
});
});
I want open modal window on app start without delay. How can I do this? Thanks!
Edit code

As i understand application starts when device is ready.
So you can use the $ionicPlatform.ready method to attach callbacks for when the device is ready.
Trigger a callback once the device is ready, or immediately if the device is already ready. Source.
angular.module('testApp', ['ionic'])
.controller('MyController', function($scope, $ionicModal, $ionicPlatform) {
$ionicModal.fromTemplateUrl('my-modal.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
$scope.openModal = function() {
$scope.modal.show();
};
$ionicPlatform.ready(function(){
$scope.openModal();
});
});

you should wait until device is ready, there are many methods for it, here is one I found:
$ionicPlatform.ready(function() {
$scope.openModal();
});

Related

How to call function of one controller from another controller AngularJs

I have two controller name called like:
AutoLoginCtrl
LoginCtrl
my facebook logout function present in Login Controller, from AutoLogin controller how could I call logout function which is Login Controller.
I have tried like this by using $rootscope and $on
LoginCtrl.js
ionApp.controller('LoginCtrl', function($scope, $state, $ionicModal, $rootScope, $q, $timeout, UserService, $ionicLoading, $ionicActionSheet) {
$scope.showLogOutMenu = function() {
var hideSheet = $ionicActionSheet.show({
destructiveText: 'Logout',
titleText: 'Are you sure you want to logout? This app is awsome so I recommend you to stay.',
cancelText: 'Cancel',
cancel: function() {},
buttonClicked: function(index) {
return true;
},
destructiveButtonClicked: function() {
$ionicLoading.show({
template: 'Logging out...'
});
// Facebook logout
facebookConnectPlugin.logout(function() {
$ionicLoading.hide();
$state.go('login');
},
function(fail) {
$ionicLoading.hide();
});
}
});
};
$rootScope.$on("LogoutFunction", function(){
$scope.parentmethod();
});
})
AutoLoginCtrl
ionApp.controller('AutoLoginCtrl', function($scope, $state, $ionicModal, $rootScope, $q, $timeout, UserService, $ionicLoading, $ionicActionSheet) {
var checkPage = "home";
$scope.logout = function() {
$rootScope.$emit("LogoutFunction", {});
}
})
You decided to use $emit a.e. child controller notifies parent controller. Is it true? AutoLoginCtrl is a child of LoginCtrl or maybe you need to use $broadcast instead?
The second problem might be:
For some reason LoginCtrl still didn't load and no one listens on LogoutFunction event.
Please check these cases
you can make a Public Class (Provider Maybe) and make a function in it that call a function 'Logout()' from 'LoginController'
and call this provider function in Your 'AutoLogin' Controller
You can have the logout function in a factory and call it from both the controllers, like this.
Factory basic demo: here
Code:
ionApp.controller('LoginCtrl', function($scope, $ionicModal, $rootScope, $q, $timeout, UserService, SharedService) {
$scope.showLogOutMenu = function() {
SharedService.logout();
};
}).factory('SharedService', function ($ionicActionSheet, $ionicLoading, $state) {
return {
logout: function () {
var hideSheet = $ionicActionSheet.show({
destructiveText: 'Logout',
titleText: 'Are you sure you want to logout? This app is awsome so I recommend you to stay.',
cancelText: 'Cancel',
cancel: function() {},
buttonClicked: function(index) {
return true;
},
destructiveButtonClicked: function() {
$ionicLoading.show({
template: 'Logging out...'
});
// Facebook logout
facebookConnectPlugin.logout(function() {
$ionicLoading.hide();
$state.go('login');
},
function(fail) {
$ionicLoading.hide();
});
}
});
}
}
}).controller('AutoLoginCtrl', function($scope, $ionicModal, $rootScope, $q, $timeout, UserService, SharedService) {
var checkPage = "home";
$scope.logout = function() {
SharedService.logout();
}
});

Modal popup in a modal popup using angular js

I'm trying to open modal popup in another modal popup. I'm getting the following error
angular.min-1.2.29.js:93 Error: [$injector:unpr]
http://errors.angularjs.org/1.2.29/$injector/unpr?p0=%24modalInstanceNewProvider%20%3C-%20%24modalInstanceNew
at Error (native)
Below is my code
Outer Modal code
var OuterController = function($scope, $modalInstance, $timeout, $http, $window, $rootScope, mydetails,$modal) {
$scope.openInnerModal = function(){
var modalInstanceNew = $modal.open({
templateUrl: '../../TEST-ANOTHER.html',
controller: InnerController,
resolve: {
lDetails: function(){
return mydetails;
}
}
});
}
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
}
}
Inner Modal Code
var InnerController = function($scope, $modalInstanceNew,$timeout, $http, $window, $rootScope,lDetails,$modal) {
alert(lDetails);
$scope.cancel = function() {
$modalInstanceNew.dismiss('cancel');
}
}
The error is saying $modalInstanceNew is not a known provider. Which is exactly true. It should be $modalInstance instead.
Try the inner modal code like this:
var InnerController = function($scope, $modalInstance,$timeout, $http, $window, $rootScope,lDetails,$modal) {
alert(lDetails);
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
}
}

Testing modalInstance.result.then

I am finally working on learning how to test using an older angularjs app I wrote. I have a few modals in my controller and I cannot figure out for the life of me how to make sure the code in 'modalInstance.result.then' is run and test against it.
I've searched Google and SO and have found examples of people testing their modals but so far they all seem to involve testing the modal controller itself.
How to I get that promise (modalInstance.result.then) to resolve? I've tried running $modal.close() but that fails to an error. I've tried mocking modalInstance and $modal in a number of ways, using jasmine spys, etc. My ignorance when it comes to testing is holding me up. Any help would be appreicated.
Here is my controller.js:
(function() {
var comment = angular.module('APP.comment', ['APP.user']);
var commentController = function($scope, $modal) {
var self = this;
self.addComment = function(newComment) {
var modalInstance = $modal.open({
templateUrl: 'views/commentModal.html',
backdrop: 'static',
windowClass: 'modal',
controller: 'commentModalController',
controllerAs: 'commentCtrl',
resolve: {
newComment: function() {
return newComment;
}
}
});
modalInstance.result.then(function(data) {
// How do I test that the function or branches here
// were run?
if (data.length === 2) {
// do this thing
} else {
// do this other thing
}
});
};
};
commentController.$inject = ['$scope', '$modal'];
comment.controller('commentController', commentController);
}());
Here is the test I have so far:
describe('Unit: commentController', function() {
var $rootScope,
$scope,
$controller,
$modal;
beforeEach(module('APP.comment'));
beforeEach(inject(function(_$rootScope_, _$controller_, _$modal_) {
$modal = _$modal_;
$rootScope = _$rootScope_;
$scope = $rootScope.$new();
$controller = _$controller_('commentController as commentCtrl', {
$scope: $scope,
$modal: $modal,
});
}));
it('should have controller defined', function() {
expect($scope.qaCtrl).toBeDefined();
});
it('should have method defined', function() {
expect($scope.qaCtrl.addComment).toBeDefined();
});
describe('$scope.commentCtrl.addComment', function() {
it('should open modal', function() {
$scope.commentCtrl.addComment();
});
});
});
I have a plnkr here:
http://plnkr.co/edit/YtYVPReH9yysZXPjbsC0?p=preview
it('should open modal', inject(function($q) {
var fakeResult = {
result: $q.when([])
};
spyOn($modal, 'open').and.returnValue(fakeResult);
$scope.commentCtrl.addComment();
$scope.$apply();
// now check that the right thing has been done, given the empty array returned
}));

Angular ui Open Modal Automatically on load page

angular-ui-modal]1 for create my site and I want to show my modal automatically when the user enter in my webpage. With ng-click is easy , I have this code:
var app = angular.module('app', ['ui.bootstrap']);
app.controller('HomeCtrl', ['$scope', '$modal', function($scope, $modal) {
$scope.openModal = function(data) {
var modalInstance = $modal.open({
templateUrl: 'modals/register.html',
resolve: {
data: function() {
return data === null ? {} : data;
}
}
});
};
}]);
But I do not know how trigger the modal when load page.
Any help? Please
You just have to call the function when the controller is loaded:
var app = angular.module('app', ['ui.bootstrap']);
app.controller('HomeCtrl', ['$scope', '$modal', function($scope, $modal) {
$scope.openModal = function(data) {
$scope.blurred = "blurredopen";
var modalInstance = $modal.open({
templateUrl: 'modals/register.html',
resolve: {
data: function() {
return data === null ? {} : data;
}
}
});
};
$scope.openModal(); // <-- Call it
}]);
Demo on JSFiddle

How to test actions which are performed in callback using Jasmine

I have two controllers and a service. In the first controller I have subscribed to an event to do some stuff. The second controller preforms some actions and when it is done, broadcasts the event. Please see the example below, the timeout is just for emulation of long running actions. I would like to test that hasLoaded is set to true using Jasmine 2.0 Please advise.
var myApp = angular.module('MyApp', []);
myApp.controller('MyCtrl1', ['$scope', 'myService', function($scope, myService) {
$scope.hasLoaded = false;
$scope.fileName = '';
myService.onLoaded($scope, function(e, data){
// I want to test the following two lines, in the really the code here is much more complex
$scope.fileName = data.fileName;
$scope.hasLoaded = true;
});
}]);
myApp.controller('MyCtrl2', ['$rootScope', '$scope', '$timeout', 'myService', function($rootScope, $scope, $timeout, myService) {
$scope.isLoading = false;
$scope.title = 'Click me to load';
$scope.load = function(){
$scope.isLoading = true;
$scope.title = 'Loading, please wait...';
$timeout(function() {
$rootScope.$emit('loaded', { fileName: 'test.txt'});
}, 1000);
};
myService.onLoaded($scope, function(){
$scope.hasLoaded = true;
});
}]);
myApp.service('myService', ['$rootScope', function ($rootScope) {
this.onLoaded = function(scope, callback) {
var handler = $rootScope.$on('loaded', callback);
scope.$on('$destroy', handler);
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<div ng-app="MyApp">
<div ng-controller="MyCtrl1">
<div ng-show="hasLoaded">{{fileName}} loaded !!!</div>
</div>
<div ng-controller="MyCtrl2">
<button ng-click="load()" ng-hide="hasLoaded" ng-disabled="isLoading" ng-bind="title"></button>
</div>
</div>
UPDATE: I have added parameter into the broadcast call to make it more closer to my case.
You really should be testing each of your pieces (controllers and services) separately. In your case, the tests for the controller that sets the hasLoaded properly really just needs to test that your register with the service correctly and that the callback does what you expect:
it("should register with the service and do the right thing when the callback is executed", inject(function ($controller, $rootScope, myService) {
var $scope = $rootScope.$new();
spyOn(myService, 'onLoaded').and.callThrough();
var ctrl = $controller('MyCtrl1', {$scope: $scope, myService: myService});
$scope.$apply();
//verify that the controller registers its scope with the service
expect(myService.onLoaded).toHaveBeenCalledWith($scope, jasmine.any(Function));
//now call the callback that was registered to see if it sets the property correctly
var mockData = {
fileName: 'some file name'
};
myService.onLoaded.calls.argsFor(0)[1]('loaded', mockData);
expect($scope.hasLoaded).toBeTruthy();
expect($scope.fileName).toBe("some file name");
}));
Then write tests for your service and other controller separately.

Resources