Close a child window in an Android app made with Angularjs - javascript

I'm coding an Android app with Angularjs and cordova, but I have a problem:
For an oauth call I need to open a new window, go to the withings site and when I come on my callback url close the window.
I have tried to use setInterval (or $interval) to check every 2 seconds if I reveived the infos by a call to my API. It works fine on a computer in chrome but when I compile the app with Cordova I never enter in the loop.
So I tried to catch an event or $watch on the url of my new window but I execute only once my function at the first url change even if my call to the API result an error.
This is my last code but I tried a lot of different tests :
var newWindow = $window.open(result.res);
var unwatch = $scope.$watch(window.location, function() {
$http.get(url)
.success(function(result) {
newWindow.close();
unwatch();
$location.path('/tab/dash');
})
.error(function(error) {
console.log(error);
});
});
If you have any idea to make this work, would be very happy.
Thanks by advance !

Finally I found a solution:
I install the cordova plugin inAppBrowser and use this code
var windowWithings = $window.open(result.res, '_blank', 'location=no');
windowWithings.addEventListener('loadstart', function(event) {
$http.get(url)
.success(function(result) {
windowWithings.close();
$location.path('/tab/dash');
})
.error(function(error) {
console.log(error);
});
});
Be careful if you don't add 'location=no' in open it won't work.

Related

How do you return a javascript object? it keeps throwing a "Converting circular structure to JSON"

I am working on an Ionic app, and I need to use firebase's phone authentication, to use that, I have to use google's recaptcha, which doesn't work in Ionic apps, so...
I made a web page that held the code for rendering the reCaptcha, and used cordova's inAppBrowser to navigate to it from inside my app.
after hours, I got everything working, and finally got the "recaptchaVerifier" object, that you need to pass to firebase.auth().signInWithPhoneNumber(phoneNumber,recaptchaVerifier)
.
I just need to pass the "recaptchaVerifier" object from the inAppBrowser, to my ionic app, I tried everything, and got stuck on a simple javascript function that would "return recaptchaVerifier" and I would grab it in Ionic, but it kept giving me Uncaught TypeError: Converting circular structure to JSON
What do I do? I just need to pass that object so I can send the verification sms from my app and continue registration/signing in.
the code for the static site that renders the recaptcha from inside the inAppBrowser:
<script>
var recaptchaVerifier;
function lol() {
alert("done");
};
$(document).ready(function() {
recaptchaVerifier = new firebase.auth.RecaptchaVerifier('gre', {
'size': 'invisible',
'callback': lol
});
recaptchaVerifier.render();
});
function getIt() {
console.log(recaptchaVerifier);
return recaptchaVerifier;
};
</script>
The code for opening the inAppBrowser and grabbing the recaptchaVerifier Object:
var myInterval;
var myValue : firebase.auth.ApplicationVerifier ;
const browser = this.inAppBrowser.create("https://demo.firebaseapp.com","_blank",
{"location":"no",clearcache:"yes",clearsessioncache:"yes"});
browser.on("loadstop").subscribe(x=>{
myInterval = setInterval(function(){
browser.executeScript({code:"getIt()"}).then(data=>{myValue = JSON.parse(data)});
},200);
});
browser.on("exit").subscribe(x=>{
clearInterval(myInterval);
this.presentAlert("Test Alert",myValue,"OK");
console.log("Adnan12 is error "+ myValue);
firebase.auth().signInWithPhoneNumber("+123456789",myValue)
.then(function (confirmationResult) {
this.presentAlert("alert title","sms sent","ok");
}).catch(function (error) {
this.presentAlert("alert title","sms NOT sent","ok");
});
});

PhantomJS onPrompt callback

I am trying to get the onPrompt callback working with PhantomJS.
Just for testing I have a basic angular application that prompts the user on initialization and displays that data on the page.
It works fine when I enter the information into the prompt manually, but it will not work when using the PhantomJS onPrompt callback.
Here's the angular app:
angular
.module('app')
.controller('test', TestController)
function TestController() {
var vm = this;
vm.$onInit = onInit;
vm.testData = '';
function onInit() {
vm.testData = prompt('Name?');
}
}
This is the code I running with PhantomJS
var page = require('webpage').create();
page.open('http://localhost:3000', function() {
console.log('test')
page.onPrompt = function(msg, defaultVal) {
console.log("MESSAGE", msg)
return "Dog";
};
page.render('test.pdf');
phantom.exit();
});
I would expect to get a console.log that says "MESSAGE" and the text from the prompt and also a screenshot of my page with "Dog" displayed.
I get a screenshot of a blank page and no console log.
I would ideally like to use this callback with node webshot as an option. webshot phantom callbacks
Thanks for the help.
There is a context in which interaction with the actual interaction with the page takes place - usually within the page.evaluate(..) function. The onPrompt callback will execute within that context and will not print to the console as you expect - I think you need to marshal the output back to the console by setting the onConsoleMessage callback first:
page.onConsoleMessage = function (msg) {
console.log(msg);
};
And then it should print to the console as you expect :)

Facebook Login not working on phone Angular Satellizer

Problem
I'm working on angular and have implemented facebook login through Satellizer. It works well on desktop, but when accessed on mobile, it sometimes work, and sometimes don't. The login pop-up is never closed when it is not working, and it opens the home page in login pop-up, while the main screen which requested login is still waiting for the pop-up to close. Any suggestion what might be wrong here?
Sample Code
This is how I'm authenticating from facebook
var commonConfig = {
popupOptions: {
location: 'no',
toolbar: 'yes',
width: window.screen.width,
height: window.screen.height
}
};
var permissions = ["public_profile","email"];
$authProvider.facebook(angular.extend({}, commonConfig, {
clientId: FacebookAppId,
url: ApiUrl+'api/v1/facebook/auth',
scope:permissions,
scopeDelimiter:','
}));
This code is called when "connect using facebook" is pressed
$scope.loginSocial = function () {
$scope.disableSubmitBtn = true;
$scope.showSpinner = true;
$auth.authenticate('facebook')
.then(function (result) {
result = angular.fromJson(result.data.code)
return AuthServerProvider.loginFb(result.facebookCode);
},function (error) {
$scope.status = 'facebook-error';
$scope.disableSubmitBtn = false;
$scope.showSpinner = false;
})
.then(function(){
$scope.disableSubmitBtn = true;
$scope.showSpinner = true;
})
This code works perfectly on desktop web browsers, but when accessed through phone browsers "$auth.authenticate('facebook')" fails most of the time.
We were facing similar problem with implementing Satellizer. It turned out that the problem was with handling the redirectUri within angular ui.router.
if you go back to the library documentation you will notice this qoute:
To avoid potential 404 errors, create server routes for each redirectUri > URL that return 200 OK. Or alternatively, you may render a custom template with a loading spinner. For the moment, a popup will not stay long > enough to see that custom template, due to 20ms interval polling, but in > the future I may add support for overriding this polling interval value.
In the above code you have mentioned, you didn't assign the redirectUri, so it will be defaulted to '/'. If you already have this route handled in a different way it might sometimes get caught by angular routes and being redirected before Satellizer can fetch it. In order to solve this just assign a redirectUri and handle it through angular routes.
For further details please read this post.

$http.success callback not being called on IE11

I have an AngularJS application that loads some data using $http service, then based on the revised data it updates corresponding html elements and updates the UI. Here is the code:
app.controller("RankingCtrl", function ($scope, PostModel, DeserializePosts, $http, $cookies){
var mainContainer = $('#mainContainer');
$scope.error = null;
function loadTop(){
$http({
type: 'GET',
url: '/ranking',
headers: {
'X-Requested-With': 'XMLHTTPRequest',
}
}).success(function(topPosts){
var mostLikedPosts = DeserializePosts(topPosts.mostLiked);
var mostViewedPosts = DeserializePosts(topPosts.mostViewed);
var mostCommentedPosts = DeserializePosts(topPosts.mostCommented);
$scope.topLiked = mostLikedPosts;
$scope.topViewed = mostViewedPosts;
$scope.topCommented = mostCommentedPosts;
}).error(function(error){
errorHandler(error.statusCode, error);
}).finally(function () {
$('#mainContainerSpinner').hide();
mainContainer.fadeIn();
});
}
loadTop();
});
My problem is, apparently the .success function is not being called, since the .finally function does get executed but the UI is not updates with any of the downloaded elements. If I ctrl-R the IE browser window, then the function works properly and the UI shows the expected elements. This issue does not happen on Chrome or FireFox.
Interestingly, when I open the F12 dev tools from IE to debug this JS code, the issue does not happen. Looks more like a bug on IE11 but I was wondering if anyone else has seen this behavior and if there are workarounds to try. Currently, my users need to refresh the page when they visit it, as only a page refresh updated the UI as expected on this AngularJS controller.
UPDATE: the UI is not getting updated because the .success function has a forEach instruction that is throwing an exception. This is happening because the browser is sending the $http request without the 'X-Requested-With' header that is specified in the code above, so the response it receives is html instead of json. Forcing a browser refresh does make the browser add this header to the http request.

How to use JQuery and custom site variables with phantomjs

I'm trying out phantomjs for browser testing and am having a few issues. My current code is below...
var page = require('webpage').create();
page.open('http://address.com', function(){
console.log('page opened');
page.evaluate(function(){
console.log('inside page eval');
varname.varaction(13633);
})
if (jQuery('#bcx_13633_iframe_overlay').is(':visible')){
console.log('it is visible');
} else {
console.log('it is not visible');
}
console.log('made it to exit');
phantom.exit();
})
I've tried using includeJS with a link to jQuery and wrapping that around everything between page.open and phantom.exit but it seems to stall out and skip that portion. I have custom actions located on the site that I can call in the console if i visit it as called in the code listed above, however, it tells me that it can't find the variable name for that either. Anyone with phantomjs experience have any tips on how to fix this?

Categories

Resources