Event not waiting for user answer inside dialog - angularjs

I need the user to confirm leaving the page if a specific condition is fulfilled. The problem is the location change is not waiting for the dialog to get the user answer.
Here's my code:
angular module 1:
...
function confirmLeavePage(e, newUrl) {
if(form.cod.value) {
customDialog.confirmDialog('Title','Leave?').then(
function(){
console.log('go to selected page');
},function(){
e.preventDefault();
});
}
}
$scope.$on("$locationChangeStart", confirmLeavePage);
...
angular module 2 :
angular.module('dialog').service('customDialog', function($mdDialog, $q, $location) {
this.confirmDialog = function(title, content){
var deferred = $q.defer();
$mdDialog.show($mdDialog.confirm({
templateUrl:'confirmDialog.html',
title : title,
textContent : content,
ok : 'Confirm',
cancel: 'Cancel'
})).then(function() {
console.log('confirmed');
deferred.resolve();
}, function() {
console.log('abort');
deferred.reject();
});
return deferred.promise;
}
});
Any ideas?

try this
function confirmLeavePage(e, newUrl) {
if(form.cod.value) {
customDialog.confirmDialog('Title','Leave?').then(
function(){
console.log('go to selected page');
});
}
e.preventDefault();
return;
}

Related

Creating new function in angularjs controller won't work

When creating new function in angularjs controller and assign it to button with ng-click and function is simple,
function toLogin() {
console.log("Entered function");
$state.go('login');
}
I tried with $scope and still does not work.
this is my controller:
'use strict';
angular.module('crudApp').controller('UserController',
['UserService', '$scope','$state', function( UserService, $scope, $state) {
var self = this;
self.user = {};
self.users=[];
self.user.enabled = false;
self.user.confirmationToken = '';
self.loggedUser = null;
self.submit = submit;
self.getAllUsers = getAllUsers;
self.createUser = createUser;
self.updateUser = updateUser;
self.removeUser = removeUser;
self.editUser = editUser;
self.reset = reset;
self.firstNamePattern=/^[A-Z][a-z]*\S$/;
self.lastNamePattern=/^[A-Z][a-z]*\S$/;
self.userNamePattern= /^\S*$/;
self.passwordPattern = /^\S*$/;
self.phonePattern = /^[0-9]+\S$/;
self.successMessage = '';
self.errorMessage = '';
self.done = false;
self.onlyIntegers = /^\d+$/;
self.onlyNumbers = /^\d+([,.]\d+)?$/;
function toLogin() {
console.log('Entered function');
// $state.go('login');
}
function submit() {
console.log('Submitting');
if (self.user.id === undefined || self.user.id === null) {
console.log('Saving New User', self.user);
createUser(self.user);
} else {
updateUser(self.user, self.user.id);
console.log('User updated with id ', self.user.id);
}
}
$scope.moje = function () {
console.log('Submitting');
if (self.user.id === undefined || self.user.id === null) {
console.log('Saving New User', self.user);
createUser(self.user);
} else {
updateUser(self.user, self.user.id);
console.log('User updated with id ', self.user.id);
}
}
function createUser(user) {
console.log('About to create user');
UserService.createUser(user)
.then(
function (response) {
console.log('User created successfully');
self.successMessage = 'User created successfully';
self.errorMessage='';
self.done = true;
self.user={};
$scope.registerForm.$setPristine();
$scope.registerForm.$setUntouched();
// $state.reload();
},
function (errResponse) {
console.error('Error while creating User');
self.errorMessage = 'Error while creating User: ' + errResponse.data.errorMessage;
self.successMessage='';
}
);
}
function updateUser(user, id){
console.log('About to update user');
UserService.updateUser(user, id)
.then(
function (response){
console.log('User updated successfully');
self.successMessage='User updated successfully';
self.errorMessage='';
self.done = true;
$scope.myForm.$setPristine();
},
function(errResponse){
console.error('Error while updating User');
self.errorMessage='Error while updating User '+errResponse.data;
self.successMessage='';
}
);
}
function removeUser(id){
console.log('About to remove User with id '+id);
UserService.removeUser(id)
.then(
function(){
console.log('User '+id + ' removed successfully');
},
function(errResponse){
console.error('Error while removing user '+id +', Error :'+errResponse.data);
}
);
}
function getAllUsers(){
return UserService.getAllUsers();
}
function editUser(id) {
self.successMessage='';
self.errorMessage='';
UserService.getUser(id).then(
function (user) {
self.user = user;
},
function (errResponse) {
console.error('Error while removing user ' + id + ', Error :' + errResponse.data);
}
);
}
function reset(){
self.successMessage='';
self.errorMessage='';
self.user={};
$scope.myForm.$setPristine(); //reset Form
}
}
]);
And and I using ui-routing and this is where I assign controller to my view:
}).state('success',{
url: '/success',
templateUrl: 'partials/successMessage',
controller: 'UserController',
controllerAs: 'sCtrl'
});
And the ftl part of code is here:
<button type="button" ng-click='sCtrl.toLogin()' class="btn btn-primary">Login</button>
It won't even print to console, but when assigning older function it works perfectly, although it is much more complicated. Ps. Sorry for bad clarification at first, I am new to community and still learning a proper way to ask question.
You're not registering the method to the controller, to do that.
Add this below in self.onlyNumbers
self.toLogin = toLogin;
You need to use $scope
$scope.toLogin = function(){
console.log("Entered function");
$state.go('login');
}

Ionic close IonicPopup when button makes an Ajax call

Am new to both angular and ionic. I have a popup in my page where i show user a input field to enter the OTP and a submit button. When i click on the submit button, I make an Ajax call to check if the OTP is valid.
But am not able to close the popup with .close method. Please help
var OTPPopup = $ionicPopup.show({
title: 'OTP VERIFICATION',
templateUrl: 'templates/login/otp.html',
scope: $scope,
buttons : [{
text: 'Confirm OTP',
type: 'button-assertive',
onTap : function(e) {
e.preventDefault();
var validateResponse = validateOTP();
validateResponse.then(function(response){
console.log('success', response);
return response;
});
}
}]
}).then(function(result){
console.log('Tapped', result);
OTPPopup.close();
});
And below is the function validateOTP
function validateOTP() {
var requestObj = {
authentication: {
email_id: $scope.loginForm.email,
security_code: $scope.OTP
}
};
return $q(function(resolve, reject) {
activateUser(requestObj, function(response){
if(response.error == null && response.data.isSuccess) {
console.log('validate correct');
resolve(response);
}
}, function(response){
return 'error';
});
});
}
activateUser is my service which makes the ajax call. Please let me know how can i acheive this.
console.log('success', response) is being printed inside the .then but after returning something from the onTap , the promise of the popup is not being called.
Ended up solving it myself.
This solution would work only if you have exactly one ionicPopup on your page. I just wrote this line of code to do the trick
$ionicPopup._popupStack[0].responseDeferred.resolve();
This automatically closes the popup. The whole code is more simpler now with normal Ajax without any q promises.
var OTPPopup = $ionicPopup.show({
title: 'OTP VERIFICATION',
templateUrl: 'templates/login/otp.html',
scope: $scope,
buttons : [{
text: 'Confirm OTP',
type: 'button-assertive',
onTap : function(e) {
// e.preventDefault() will stop the popup from closing when tapped.
e.preventDefault();
validateOTP();
}
}]
});
and in the next function
function validateOTP() {
var requestObj = {
authentication: {
email_id: $scope.loginForm.email,
security_code: $scope.loginForm.OTP
}
};
activateUser(requestObj, function(response){
if(response.error == null && response.data.isSuccess) {
localStorage.setLocalstorage = response.data.user[0];
$ionicPopup._popupStack[0].responseDeferred.resolve();
$state.go('dashboard.classified');
}
}, function(response){
});
}
you don't need call e.preventDefault();
you just only return the validateOTP promise
ionicPopup will waiting the promise then close popup
var OTPPopup = $ionicPopup.show({
title: 'OTP VERIFICATION',
template: 'templates/login/otp.html',
scope: $scope,
buttons : [{
text: 'Confirm OTP',
type: 'button-assertive',
onTap : function() {
return validateOTP();
}
}]
}).then(function(result){
console.log('closed', result); // result is the activateUser resolve response
});

Pass parameter from controller to services in angularjs

How can i have one service or factory receiving two parameters from many controllers?
One parameter for the url, other for the file name to be stored on the filesystem.
I will have many controllers using this service, each passing his own url and filenames that reads the url and generate a pdf.
I will always store the last downloaded pdf providing an "open last pdf" button, that will use the name parameter.
I will have a "generate new pdf" button coming from the url.
I do follow this tutorial https://blog.nraboy.com/2014/09/manage-files-in-android-and-ios-using-ionicframework/ and everything works fine.
I am using cordova file-transfer and inappbrowser cordova plugins
These sections will receive the parameters :
dirEntry.getFile("pdf-number-1.pdf",
ft.download(encodeURI("http://www.someservice.com"),p,
My attempt always trigger the message unknow pdfService provider
Wich concepts of angular i am missing ? How can i fix it ?
In services.js i have :
.service('pdfService', function($scope, $ionicLoading){
if( window.cordova && window.cordova.InAppBrowser ){
window.open = window.cordova.InAppBrowser.open;
console.log("InAppBrowser available");
} else {
console.log("InAppBrowser not available");
}
this.download = function() {
$ionicLoading.show({
template: 'Loading...'
});
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) {
fs.root.getDirectory("ExampleProject",{create: true},
function(dirEntry) {
dirEntry.getFile(
"pdf-number-1.pdf",
{
create: true,
exclusive: false
},
function gotFileEntry(fe) {
var p = fe.toURL();
fe.remove();
ft = new FileTransfer();
ft.download(
encodeURI("http://www.someservice.com"),
p,
function(entry) {
$ionicLoading.hide();
$scope.imgFile = entry.toURL();
},
function(error) {
$ionicLoading.hide();
alert("Download Error Source -> " + error.source);
},
false,
null
);
},
function() {
$ionicLoading.hide();
console.log("Get file failed");
}
);
}
);
},
function() {
$ionicLoading.hide();
console.log("Request for filesystem failed");
});
}
this.load = function() {
$ionicLoading.show({
template: 'Loading...'
});
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) {
fs.root.getDirectory(
"ExampleProject",
{
create: false
},
function(dirEntry) {
dirEntry.getFile(
"pdf-number-1.pdf",
{
create: false,
exclusive: false
},
function gotFileEntry(fe) {
$ionicLoading.hide();
$scope.imgFile = fe.toURL();
alert(fe.toURL());
window.open(fe.toURL(), '_system', 'location=no,toolbar=yes,closebuttoncaption=Close PDF,enableViewportScale=yes');
},
function(error) {
$ionicLoading.hide();
console.log("Error getting file");
}
);
}
);
},
function() {
$ionicLoading.hide();
console.log("Error requesting filesystem");
});
}
});
And in the controller :
.controller('SomeCtrl', function($scope, $ionicPopup, pdfService) {
...
pdfService.download = function(url) {
console.log('pdfService download');
}
pdfService.load = function() {
console.log('pdfService load');
}
You will need to inject the service to your controllers and call a function with the two params you want as your arguments.
eg.
.service('pdfService', function(){
var lastUrl;
var lastFileName
return {
createPdf(url, fileName){
//do processing
lastUrl = url;
lastFileName = fileName
},
loadLastPdf(){
//use lastUrl and lastFileName
}
}
}
and in your controller:
.controller('SomeCtrl', function(pdfService) {
pdfService.createPdf('http://example.com', 'file.pdf');
// or pdfService.loadLastPdf();
}
That being said, the error you are reporting means that the DI is unable to find a service with the name pdfService to inject to your controller. This might be because you forgot to include the service.js file to your html as a script tag (if you are doing it like that) or you forgot to add it as a dependency using require (if you are using sth like browserify) or maybe if you are minifying your code since you are not using the minsafe syntax

Is there a better way to disable a button when posting data in AngularJS?

In my projects at the moment, I use something along these lines for AJAX forms.
$scope.posting = false;
$scope.submitForm = function(form){
log(form);
log((!form.$invalid) ? 'Is valid' : 'Contains errors');
$scope.posting = true;
$http.post('/modules/ajax/addModule', $scope.module)
.success(function(data, status, headers, config){
data = data.data;
log(data);
$scope.posting = false;
if(data.error){
alert(data.message);
}
})
.error(function(data, status, headers, config){
data = data.data;
log(data);
$scope.posting = false;
});
}
and on the submit button, <input ng-disabled="form.$invalid || posting" ... />
Whilst it's not much to type code, manually switching the bool value seems a little non Angular to me. Is there anyway to tell if an $http.post is still active?
just write a directive which will disable and enable the button on http calls, like below
app.directive('onClick', function() {
return {
scope: {
onClick: '&'
},
link: function(scope, iElement, iAttrs) {
iElement.bind('click', function() {
iElement.prop('disabled',true);
scope.onClick().finally(function() {
iElement.prop('disabled',false);
})
});
}
};
});
note : onClick function should return a promise for this to work
Checkout this plunker to see it in action
I use angular-ladda for button with spinner while call is in progress
What I ended up doing was adding this code to my global JS file.
app.run(function($rootScope, $http) {
$http.defaults.transformRequest.push(function (data) {
$rootScope.$isPosting = true;
return data;
});
$http.defaults.transformResponse.push(function(data){
$rootScope.$isPosting = false;
return data;
})
});
Then I can just use
<a ng-disabled="isPosting" ...

AngularJS hide div after delay

While creating my app in AngularJS (awesome framework!) I stuck in one task: how to show and hide hidden div (ng-show) after some action.
Detailed description: using AngularUI $modal service I'm asking if user wants to perform action, if yes, I run service to POST request via $http to send which item I want to delete. After it finished I want to show hidden div with information, that process has accomplished successfully. I created a simple service with $timeout to set div's ng-show and hide after some time but it doesn't update variable assigned to ng-show directive. Here is some code:
Controller for listing and deleting items
$scope.deleteSuccessInfo = false; //variable attached to div ng-show
$scope.deleteCluster = function(modalType, clusterToDelete) {
modalDialogSrvc.displayDialog(modalType)
.then(function(confirmed) {
if(!confirmed) {
return;
}
clusterDeleteSrvc.performDelete(itemToDelete)
.then(function(value) {
//my attempt to show and hide div with ng-show
$scope.deleteSuccessInfo = showAlertSrvc(4000);
updateView(itemToDelete.itemIndex);
}, function(reason) {
console.log('Error 2', reason);
});
}, function() {
console.info('Modal dismissed at: ' + new Date());
});
};
function updateView(item) {
return $scope.listItems.items.splice(item, 1);
}
Part of service for deleting item
function performDelete(itemToDelete) {
var deferred = $q.defer(),
path = globals.itemsListAPI + '/' + itemToDelete.itemId;
getDataSrvc.makeDeleteRequest(path)
.then(function() {
console.log('Item removed successfully');
deferred.resolve({finishedDeleting: true});
}, function(reason) {
console.log('error ', reason);
deferred.reject(reason);
});
return deferred.promise;
}
return {
performDelete: performDelete
};
Simple service with $timeout to change Boolean value after some time
angular.module('myApp')
.service('showAlertSrvc', ['$timeout', function($timeout) {
return function(delay) {
$timeout(function() {
return false;
}, delay);
return true;
};
}]);
I tried $scope.$watch('deleteSuccessInfo', function(a, b) {...}) with no effect. How to apply false after some delay? Or maybe You would achieve this in other way?
Thank You in advance for any help!
Change the implementation of the showAlertSrvc service, like this:
angular.module('myApp')
.service('showAlertSrvc', ['$timeout', function($timeout) {
return function(delay) {
var result = {hidden:true};
$timeout(function() {
result.hidden=false;
}, delay);
return result;
};
}]);
And then change thes 2 lines:
The declaration of deleteSuccessInfo should be like this:
$scope.deleteSuccessInfo = {};
And then do this:
$scope.deleteSuccessInfo = showAlertSrvc(4000);
And finally in your view do this "ng-show=!deleteSuccessInfo.hidden"
Example

Resources