InAppBrowser Events handling issue - angularjs

I am working on mobile app using:
Ionic 2.1.4
Cordova 6.4.0
Angular 1.5.3
I've one view with external url using InAppBrowser plugin and I have a link in this website should redirect to certain view in my app
this issue is $location.url() not redirecting and not working at all, but when I tested the event I found it trigger normally.
here is my full code
angular.module('yogipass').controller('iframe',function ($location) {
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
console.log('here');
var ref=cordova.InAppBrowser.open('http://192.168.42.218/index.html', '_blank', 'location=no');
ref.addEventListener('loadstart', function(event) {
if (event.url.match("mobile/login")) {
console.log('worked!') // this logged normally
$location.url('/login');
ref.close();
}
});
}
])

You have to run digest cycle manually as you are changing location path from asynchronous event which is outside angular context.
Do wrap you code in $timeout function, which will fire up digest cycle. Apparently that will help to update location.
$timeout(function(){
$location.url('/login');
})

Related

Angular routing not working in Samsung Tizen default browser

I'm facing an strange issue in Samsung Tizen phones. I'm using
$location.path('/someurl')
In my Angular mobile web app, URL has been updated, but the corresponding view is not coming up, i.e. the previous view has not been replaced by the new one. All my code works fine in desktop and other mobile phones.
I don't know what I'm doing wrong. I have already used $timeout but no success. Any suggestion?
Use $apply() like this.
app.run(function ($location, $window, $rootScope) {
$window.addEventListener('message', function(e) {
$rootScope.$apply(function() {
$location.path("/abc");
console.log($location.path());
});
});
});

Ionic view not refreshing data from API

We have an Ionic app which polls a node/express API.
When the app starts it fetches the JSON data correctly from the API. When we update the data and fetch it again from the Ionic app, we still see the old data from the time that the app was launched.
We've tried to clear both the Angular cache and the Ionic cache in a variety of ways, but that doesn't seem to make a difference.
Things we've tried are:
$ionicConfigProvider.views.maxCache(0);, cache-view="false" on the template, setting cache: false on the state, tried accessing the state via $state.go($state.currentState, {}, {reload : true});, $ionicHistory.clearHistory(); and $ionicHistory.clearHistory();, $route.reload and $window.location.reload.
Controller:
function contactsController(Contacts, $stateParams) {
var vm = this;
var params = $stateParams.id;
Contacts.getAllContacts.then(function success(response) {
vm.data = response.data;
vm.selectedContact = response.data[params];
});
}
Factory
function contactsFactory($http, $stateParams) {
return {
getAllContacts: $http.get('https://api-call'),
update: function(url) {
$http.patch('https://api-call/update', [$stateParams.id, url]);
},
};
}
Express Back end
app.get('/', function (req, res) {
ref.once("value", function(snapshot){
res.send(snapshot.val());
});
});
app.patch('/update', function(req, res) {
var id = req.body[0];
ref.child(id).update({"imageURL": req.body[1]});
});
Thanks
Modify your view like this
<ion-view cache-view="false" view-title="My Title!">
Try console.log(vm) and verify that the updated data are obtained. If its only the view thats not being updated despite updated data being logged, I would try the following along with cache-view="false".
$scope.apply(function (){
// update your view here
vm.data = response.data;
vm.selectedContact = response.data[params];
});
By using Firebase's once() you have effectively removed all callbacks attached to value besides the first one:
Listens for exactly one event of the specified event type, and then
stops listening
Try switching to on() instead.
app.get('/', function (req, res) {
ref.on("value", function(snapshot){
res.send(snapshot.val());
});
});
It may be that your issue is not related to caching at all...
When I install Ionic 2 Open layers map on android device, i can see Open layers map successfully on the android screen. But when i close it and open the app again, i cant see the map. To solve this problem , what i do is: i uninstall the app, restart my device, then reinstall the app, after that i can see the map.
Please provide me a permanent fix.
Placing this in app config worked for me with
$ionicConfigProvider.views.maxCache(0);
$ionicConfigProvider dependency in config.

app closing while back button is pressed

I am developing a mobile app using angular js, cordova , ionic and using intel xdk to build. Here my problem is whenever i click the back button in mobile device, app get closed itself instead of redirecting to previous page.Is that ionic problem?
Also tried addEventListener
document.addEventListener("backbutton", onBackKeyDown, false);
function onBackKeyDown() {
alert();
$location.path('/sandhyavMor');
}
Here, still the app getting closed after firing the alert. Also i am using intel xdk media plugin.
so what may be the problem.
Try using this code.Use it in app.js
angular.module('starter', ['ionic', 'starter.controllers'])
.run(function ($ionicPlatform,$state,$log, $rootScope,$ionicHistory) {
$ionicPlatform.registerBackButtonAction(function (e) {
if ($ionicHistory.backView()) {
$ionicHistory.goBack();
} else {
$state.go($rootScope.previousState);
}
e.preventDefault();
return false;
}, 101);
});
Are you sure there is a previous view to go back to? Are there tabs in your app?

How to disable repeat event $routeChangeSuccess on page?

I have code that detects routing in controller Angular JS:
$scope.$on('$routeChangeSuccess', function() {
if($routeParams.user){
// AJAX
}
});
When I am on page with URL for this routing and do new AJAX request then the previous code is executed again. How to disable repeating executable?

Cordova + Angularjs + Device Ready

I am developing a mobile application using Cordova and AngularJS. How do I restrict bootstrapping of AngluarJS before Cordova device ready. Basically I don't want to use any of AngularJS controllers before device ready.
Manually bootstrap your Angular app:
Remove your ng-app attribute from your HTML code, so Angular doesn't start itself.
Add something like this to you JavaScript code:
document.addEventListener("deviceready", function() {
// retrieve the DOM element that had the ng-app attribute
var domElement = document.getElementById(...) / document.querySelector(...);
angular.bootstrap(domElement, ["angularAppName"]);
}, false);
Angular documentation for bootstrapping apps.
I'm using the following solution, which allows AngularJS to be bootstrapped when running with Cordova as well as when running directly in a browser, which is where much of my development takes place. You have to remove the ng-app directive from your main index.html page since that's what the manual bootstrapping is replacing.
UPDATE: I've since switched to the following method, which I think is cleaner. It works for Ionic as well as vanilla Cordova/PhoneGap. It should be the last bit of JavaScript to run - perhaps inside a script tag before the /body tag.
angular.element(document).ready(function () {
if (window.cordova) {
console.log("Running in Cordova, will bootstrap AngularJS once 'deviceready' event fires.");
document.addEventListener('deviceready', function () {
console.log("Deviceready event has fired, bootstrapping AngularJS.");
angular.bootstrap(document.body, ['app']);
}, false);
} else {
console.log("Running in browser, bootstrapping AngularJS now.");
angular.bootstrap(document.body, ['app']);
}
});
Here's the older solution I used:
// This is a function that bootstraps AngularJS, which is called from later code
function bootstrapAngular() {
console.log("Bootstrapping AngularJS");
// This assumes your app is named "app" and is on the body tag: <body ng-app="app">
// Change the selector from "body" to whatever you need
var domElement = document.querySelector('body');
// Change the application name from "app" if needed
angular.bootstrap(domElement, ['app']);
}
// This is my preferred Cordova detection method, as it doesn't require updating.
if (document.URL.indexOf( 'http://' ) === -1
&& document.URL.indexOf( 'https://' ) === -1) {
console.log("URL: Running in Cordova/PhoneGap");
document.addEventListener("deviceready", bootstrapAngular, false);
} else {
console.log("URL: Running in browser");
bootstrapAngular();
}
If you run into problems with the http/https detection method, due to, perhaps, loading a Cordova app into the phone from the web, you could use the following method instead:
function bootstrapAngular() {
console.log("Bootstrapping AngularJS");
// This assumes your app is named "app" and is on the body tag: <body ng-app="app">
// Change the selector from "body" to whatever you need
var domElement = document.querySelector('body');
// Change the application name from "app" if needed
angular.bootstrap(domElement, ['app']);
}
// This method of user agent detection also works, though it means you might have to maintain this UA list
if (navigator.userAgent.match(/(iOS|iPhone|iPod|iPad|Android|BlackBerry)/)) {
console.log("UA: Running in Cordova/PhoneGap");
document.addEventListener("deviceready", bootstrapAngular, false);
} else {
console.log("UA: Running in browser");
bootstrapAngular();
}
Note that you still need the same bootstrapAngular function from the first example.
Why manually bootstrap AngularJS with Cordova/PhoneGap/Ionic?
Some people getting here might not know why you would want to do this in the first place. The issue is that you could have AngularJS code that relies on Cordova/PhoneGap/Ionic plugins, and those plugins won't be ready until after AngularJS has started because Cordova takes longer to get up and running on a device than the plain old Javascript code for AngularJS does.
So in those cases we have to wait until Cordova/PhoneGap/Ionic is ready before starting up (bootstrapping) AngularJS so that Angular will have everything it needs to run.
For example, say you are using the NG-Persist Angular module, which makes use of local storage for saving data on a browser, iOS Keychain plugin when running on iOS, and the cordova-plugin-file when running on Android. If your Angular app tries to load/save something right off the bat, NG-Persist's check on window.device.platform (from the device plugin) will fail because the mobile code hasn't completed startup yet, and you'll get nothing but a white page instead of your pretty app.
If you are using Ionic, this solution works for browsers and devices. Credit to romgar on this thread.
window.ionic.Platform.ready(function() {
angular.bootstrap(document, ['<your_main_app']);
});
Still need to remove ng-app from your DOM element.
This solution became more robust when I used:
angular.element(document).ready(function () {
var domElement = document.getElementById('appElement');
angular.bootstrap(domElement, ["angularAppName"]);
});
UPDATE
My suggestion was to put the above within the appropriate deviceready function, e.g.:
document.addEventListener("deviceready", function() {
angular.element(document).ready(function () {
var domElement = document.getElementById('appElement');
angular.bootstrap(domElement, ["angularAppName"]);
});
}, false);
On using the solution from TheHippo:
document.addEventListener("deviceready", function() {
// retrieve the DOM element that had the ng-app attribute
var domElement = document.getElementById(...) / document.querySelector(...);
angular.bootstrap(domElement, ["angularAppName"]);
}, false);
It doesn't work in the browser because "cordova.js" gets resolved by the Cordova or Phonegap building process and is not available in your localhost or emulated testing environment.
Thus the "deviceready" event is never fired. You can simply fire it manually in your browsers console.
var customDeviceReadyEvent = new Event('deviceready');
document.dispatchEvent(customDeviceReadyEvent);
Also make sure, that the bootstrap of angular gets triggered after setting all of you angular modules/controllers/factories/directives etc.
In most cases you probably don't need to block loading your angular app until after deviceready (mind that it can take several seconds for deviceready to fire if you have a lot of plugins).
Instead you can use something like this lib (https://github.com/arnesson/angular-cordova) which solves the deviceready issues for you by automatically buffering calls and then execute them after deviceready has been fired.

Resources