Ionic 5 | Detect app closing or going to background - ionic-framework

I Cannot detect when the app is closing or going to background on ionic 5. Pause event is not working. What i tried is this:
ionViewDidLoad() {
this.pause = this.platform.pause.subscribe(() => {
this.experimentService.stop().then(res => {
//I do something that doing things to a raspberry pi (don't know if that matters), that take some time to respond
});
});
}
ionViewWillLeave() {
this.pause.unsubscribe();
}

Thanks to #E. Maggini comment, the problem was that I did not use async.
Solution:
this.platform.pause.subscribe(async () => {
this.experimentService.stop().then(res => {
});
});

Related

ionic - back button exit app not working in Ionic 5

I am using Ionic version 5.4.16 and i am trying to close the app by hardware back button with a alert message for confirm to exit. I have checked a lot of tutorials for the same and everywhere i saw 2 ways to achieve that --
this.platform.exitApp();
and
navigator.app.exitapp()
and
navigator.["app"].exitapp();
But none of these option are working in Ionic 5, its not recognizing the function exitApp().
So how to achieve the same if anyone has faced the same issue do suggest, thank you.
To close the app, you must configure the following:
import { Plugins } from '#capacitor/core';
const { App } = Plugins;
App.exitApp();
Try to paste this code.
public unsubscribeBackEvent: any;
ionViewDidEnter() {
this.initializeBackButtonCustomHandler();
}
initializeBackButtonCustomHandler(): void {
this.unsubscribeBackEvent = this.platform.backButton.subscribeWithPriority(999999, () => {
if(window.confirm('Do you want to exit the app?'))
{
navigator['app'].exitApp();
}
});
}
ionViewWillLeave() {
this.unsubscribeBackEvent.unsubscribe();
}
I hope it's done.

How to close Camera using phonegap-barcode-scanner plugin within service IONIC

I am using phonegap-barcodescanner-plugin to read qr while a service is reading instant payments on background.
I am detecting a new instant payment in the service and launching an event subscribed in the page where the barcodeScanner is launched
event.subscribe('instant-payment', (val) => {
console.log("Hi--------------", val)
this.navCtrl.pop()
});
the event is correctly fired and the log is ok but I'm trying to do a navCtrl.pop() and the Activity is never closed, I thought was going to work same way like cancelling scanner
scan() {
this.barcodeScanner.scan(this.options).then(barcodeData => {
if (barcodeData.cancelled == true) {
this.navCtrl.pop()
} else {
}
}).catch(err => {
console.log('Error', err);
});
}
Is there anyway to force close barcodeScanner and go back to the last "IonicPage".
Thanks for any help.

Protractor not waiting for modal

I have a modal that shows up in a protractor test. When I run the test case solo, it works perfectly, but when I run it as part of the larger file (currently 10 cases, some lengthy) it slows things down and, as a result, the modal is slower to open and close. The chain effect is that, when I try to click on a button on the page, it crashes since the modal (which was supposed to be closed by now) is still there and blocking the button.
How can I properly sense when the modal is open/closed so that I can work around this?
Thanks!
(Also, this is an AngularJS application)
These are my helper functions for manual waiting:
static async forElementAbsent(element) {
return await new Promise<any>((resolve) => {
browser.driver.wait(ExpectedConditions.stalenessOf(element), 10000,
`Timed out waiting for element to be absent`).then(() => {
resolve();
});
});
}
static async forElementPresent(element) {
return await new Promise<any>((resolve) => {
browser.driver.wait(ExpectedConditions.presenceOf(element), 10000,
`Timed out waiting for element to be present`).then(() => {
resolve();
});
});
}
In our tests, we are waiting for modals to be displayed manually. We have helper functions such as
export async function forCondition(condition: () => boolean | PromiseLike<boolean>, timeout = 20000): Promise<boolean> {
try {
return await browser.wait(condition, timeout);
} catch (err) {
return false;
}
}
Given function waits for a condition to fullfill. So in your particular case you would have to find out the css selector of the modal which is displayed.
Let's say the selector is by.css('.modal.visible'), then we would have to write something like the following if we wanted to wait for the modal to be displayed:
t.it('modal should be displayed', async function() {
// wait for modal to be displayed
var result = await forCondition(function() {
return element(by.css('.modal.visible')).isDisplayed();
});
expect(result).toBeTruthy();
});

How to detect when Mapbox/Leaflet enters or exits fullscreen mode

How can I detect when Mapbox or Leaflet enters or exits fullscreen mode?
I found this answer where someone said this:
Documentation says:
map.on('fullscreenchange', function () {
if (map.isFullscreen()) {
console.log('entered fullscreen');
} else {
console.log('exited fullscreen');
}
});
If doesnt work, use this instead:
map.on('enterFullscreen', function(){
});
map.on('exitFullscreen', function(){
});
I tried that, as well as a few variations of the event type parameter. No dice.
Also, the documentation doesn't mention an event for this.
Note that I am using Mapbox GL JS.
I know this is a late response but to anyone in the future this is how I approached it (for mapbox GL JS (without leaflet).
map.on("resize", () => {
if (document.fullscreenElement) // do something
});
You can give the map wrapper div a name and exclusively also check if the map is what triggered the fullscreen event
map.on("resize", () => {
if (document.fullscreenElement?.attributes.name.value === "mapWrapper") // do something
});
And if you are using React you can use a state to hold this information.
const [isFullScreen, setIsFullScreen] = useState();
...
map.on("resize", () => {
setIsFullScreen(
document.fullscreenElement?.attributes.name.value === "mapWrapper"
);
});
...
if (isFullScreen) //do something
This is actually really simple. You don't need anything from Leaflet or Mapbox. Just use an event listener on the document object.
let fullScreenChange;
if ('onfullscreenchange' in window.document) {
fullScreenChange = 'fullscreenchange';
} else if ('onmozfullscreenchange' in window.document) {
fullScreenChange = 'mozfullscreenchange';
} else if ('onwebkitfullscreenchange' in window.document) {
fullScreenChange = 'webkitfullscreenchange';
} else if ('onmsfullscreenchange' in window.document) {
fullScreenChange = 'MSFullscreenChange';
}
function onFullscreenChange() {
// Your stuff.
}
window.document.addEventListener(fullScreenChange, onFullscreenChange);

Ionic2: Unsubscribe Event to Avoid Duplicate Entries?

I've followed this tutorial which outlines adding monitoring beacons in an Ionic 2 application. I have it working great: when the view loads, it initializes and begins listening for beacons:
home.ts
ionViewDidLoad() {
this.platform.ready().then(() => {
this.beaconProvider.initialise().then((isInitialised) => {
if (isInitialised) {
this.listenToBeaconEvents();
}
});
});
}
This calls the listenToBeaconEvents function which populates a list in the view with all of the beacons:
home.ts
listenToBeaconEvents() {
this.events.subscribe(‘didRangeBeaconsInRegion’, (data) => {
// update the UI with the beacon list
this.zone.run(() => {
this.beacons = [];
let beaconList = data.beacons;
beaconList.forEach((beacon) => {
let beaconObject = new BeaconModel(beacon);
this.beacons.push(beaconObject);
});
});
});
}
I'm able to stop ranging using this.beaconProvider.stopRanging() that calls a function from the below function:
beacon-provider.ts
stopRanging() {
if (this.platform.is('cordova')) {
// stop ranging
this.ibeacon.stopRangingBeaconsInRegion(this.region)
.then(
() => {
console.log('Stopped Ranging');
},
error => {
console.error('Failed to stop monitoring: ', error);
}
);
}
}
The problem I'm having is this - in the original tutorial the beacon list is shown at the root, there's no other navigation. I've moved it to a different view, and if the user exits and re-enters the view, it re-initializes and loads everything, resulting in duplicate list entries.
I've tried creating a function within beacon-provider.ts to call before the view exits, but I can't figure out how to keep the subscriptions/events from duplicating.
I've tried this.delegate.didRangeBeaconsInRegion().unsubscribe(), and some other variations but they all result in runtime errors.
In your case you are using Ionic's Events API which has its own unsubscribe(topic, handler) function.
In your component, whenever you need to unsubscribe, you should call this with the same topic:
this.events.unsubscribe(‘didRangeBeaconsInRegion’);
This will remove all handlers you may have registered for the didRangeBeaconsInRegion.
If you want to unsubscribe one specific function, you will have to have registered a named handler which you can send with unsubscribe.
this.events.unsubscribe(‘didRangeBeaconsInRegion’,this.mySubscribedHandler);
And your home.ts would look like:
mySubscribedHandler:any = (data) => {
// update the UI with the beacon list
this.zone.run(() => {
this.beacons = [];
let beaconList = data.beacons;
beaconList.forEach((beacon) => {
let beaconObject = new BeaconModel(beacon);
this.beacons.push(beaconObject);
});
});
}
listenToBeaconEvents() {
this.events.subscribe(‘didRangeBeaconsInRegion’,this.mySubscribedHandler);
}