Ionic close IonicPopup when button makes an Ajax call - angularjs

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
});

Related

Event not waiting for user answer inside dialog

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;
}

cannot call function from within ionic popup

I am new to ionic.
I have a function in my controller. I want to call that function from another function which has ionic popup. but, the function call does not happen.
Here is the code
Function with ionic popup
$scope.show = function() {
var myPopup = $ionicPopup.show({
templateUrl: 'views/d.html',
cssClass: 'custom-ipopup',
title: 'Welcome to myapp',
subTitle: 'enter username.',
scope: $scope,
buttons: [
{ text: '<b>Cancel</b>' },
{
text: 'Test',
type: 'button-positive',
onTap: function(e) {
e.preventDefault();
scope.usernameCheck = usernameLookup();
console.log(scope.usernameCheck); //prints undefined
}
}
]
});
};
usernameLookup() function i am calling from $ioninPopup.show()'s onTap()
$scope.usernameLookup = function() {
console.log('inside usernameLookup()');
$scope.lookingDB = true;
$scope.unamePresent = 3;
$http({
method: 'GET',
url: $rootScope.cred.url + '/api',
params: {
}
}).success(function(d) {
$scope.lookingDB = false;
$scope.unamePresent = 1;
return $scope.unamePresent
}).error(function(d) {
$scope.lookingDB = false;
$scope.unamePresent = 2;
return $scope.unamePresent
});
};
Can someone tell me why is it not calling usernameLookup() function? Both these methods are in same controller.

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

Clear form after submit and disable form in angular service

I create a service to upload content.
it takes 4 argument
which folder to update
the content
set the form to disabled
clear form after submit
create: function(folderID, text, o, master) {
o.isDisabled = true;
ob = {
text: text,
media: 'Pending',
createdBy: $rootScope.AUTH.user.uid,
createdTime: Firebase.ServerValue.TIMESTAMP
};
_firebaseRef.files.child(folderID).push(ob, function(error) { $timeout(function() {
if (error) {
alert('Create file failed, please try again'); o.isDisabled = false;
} else {
o.isDisabled = false;
angular.copy(master, o);
};
});
});
},
So when in controller.
service.create(folderID, 'hello world', $scope.file, $scope.master);
My question
How can I omit the 3rd and 4th arguments?

Validate on save and save().complete - in backbone

I have problem with validation in my model. It seems that it is impossible to use save().complete(function() {..... in the same time as validation- here is the code:
my model:
App.Models.Task = Backbone.Model.extend({
defaults: {
title:'',
completed: 0
},
validate: function (attrs, options) {
if(attrs.title == '' || attrs.title === undefined) {
return "fill title pls"
}
},
urlRoot: 'tasks'
});
and then in my view i try to save it in add method :
App.Views.TaskAdd = Backbone.View.extend({
tagName: 'div',
template: template('taskTemplateAdd'),
events : {
'click .addTask' : 'add'
},
initialize: function () {
this.model.on('add',this.render, this)
},
add : function () {
var title = $("#addNew input:eq(0)").val();
var completed = $("#addNew input:eq(1)").val();
this.model.set('title', title);
this.model.set('completed', completed);
this.model.save({},
{
success: function (model, response) {
console.log("success");
},
error: function (model, response) {
console.log("error");
}
}).complete(function () {
$("<div>Data sent</div>").dialog();
$('#list').empty();
});
},
render: function () {
this.$el.html(this.template(this.model.toJSON()));
return this
}
});
when validate fires i get error :
Uncaught TypeError: Object false has no method 'complete'
I understand that it tries probably to run complete callback on the return value but how to solve this problem ???
Model.save is documented returning the jqHXR object if successful or false if not.
So, unless your server never fails, you need to handle the case where save returns false. Here's a simple example of the logic you would need:
var valid=this.model.save();
if(!valid) {
// do something when not valid
else {
valid.complete(function() {}); // this is a jqHXR when valid
}
And, as of jQuery 1.8, the use of complete is deprecated. You should consider using always instead.
Use.
...
add : function () {
var self = this;
this.model.save({'title':$("#addNew input:eq(0)").val(),'completed':$("#addNew input:eq(1)").val()},
{
success: function (model, response) {
console.log("success");
self.complete();
},
error: function (model, response) {
console.log("error");
self.complete();
}
});
},
complete: function () {
$("<div>Data sent</div>").dialog();
$('#list').empty();
},
...
model.save() performs a validation first (validate method on the model). If it successfull, it then does the POST/PUT to the server. In other words, you get a false if the client side validation fails. It won't post to server then. You can't use the deferred object if this fails because false.always() will probally result in an error.
Alsoo, if you don't pass a wait: true in the model.save options, it will update the model with its validated object. I usually pass wait: true just to be sure. (I don't want to render the element twice).
If the model fails the client side validation, then it should also fail the server side validation. In this case there is an "invalid" event to listen to. So you only should be interested in the success call. Which in theory should only be interesting if it really has updates (would fire a "change" event)
add: {
var self = this;
this.model.on('invalid', function(error){
console.log(error, 'model is invalid. Check model.validate')
});
this.model.on('change', function(model){
console.log(model.toJSON(), 'model has successfully changed')
});
this.model.on('error', function(error){
console.log("server failed to acknowledge (server connection not made)")
});
this.model.on('sync', function(resp){
console.log("server successfull acknowledged (server connection made)")
});
this.model.save(
{
title:$("#addNew input:eq(0)").val(),
completed:$("#addNew input:eq(1)").val()
},
{
wait: true,
success: function (model, response) {
console.log("success");
#fires an change event if the model is updated
self.complete();
},
error: function (model, response) {
console.log("error");
self.complete();
}
}
);
},
complete: function(){
console.log("show this")
}

Resources