How to stop functions when leaving the page in Ionic 4 - ionic-framework

I am working in my Ionic 4 app and I want to stop the functions when the page will leave.
This is my tab4.page.ts:
async getUserDetail(){
this.dataexists = false;
this.userActiveChallanges = [];
let me=this;
const loading = await this.loadingController.create({
message: '',
// duration: 2200,
translucent: true,
spinner: 'crescent',
showBackdrop: false,
cssClass: 'my-loading-class'
});
await loading.present();
this.userActiveChallanges=[];
this.storage.get('USERPROFILE').then(userObj => {
// console.log('User Profile :',userObj);
me.userprofile = userObj;
me.sendFitDatafunction(userObj);
me.myapi.apiCall('userActiveChallenges/'+userObj.id,'GET','').subscribe((data) => {
// console.log(data);
me.response=data;
loading.dismiss();
if(me.response.status === 'success'){
if(me.response && me.response.data && me.response.data.length>0){
this.userActiveChallanges=me.response.data;
this.flip(this.userActiveChallanges[0].challenge_id);
}
this.dataexists = true;
} else{
this.userActiveChallanges = '';
this.dataexists = true;
}
}, error => { loading.dismiss(); console.log(error); });
});
}
ionViewWillLeave() {
}
I want to stop this function when the page will leave because when I am not getting any response nor any error from the api the loader keeps running and when I move to the other page, it is showing there.
So, I want to stop the function when the page will leave.
Any help is much appreciated.

instead of local const loading, declare it as a property of your ts class (tab4).
now change your code and assign loader to it:
replace: const loading
with:
this.loading
Now inside ionViewWillLeave call:
ionViewWillLeave() {
if (this.loading) { this.loading.dismiss() }
}

Well, I don't know the function to stop your function, but to make something when you leave a page, you make it in IonViewDidLeave()

Related

unininstall PWA Manually

The following code can be used to install the program in the PWA:
var fab = document.querySelector('#fab');
var deferredPrompt;
fab.addEventListener('click', function () {
if (deferredPrompt) {
deferredPrompt.prompt();
deferredPrompt.userChoice.then(function (choice) {
if (choice.outcome === 'dismissed') {
console.log('installation was cancelled');
} else {
console.log('User Added To Home Screen');
}
});
deferredPrompt = null;
}
});
//********************************************************************
window.addEventListener('beforeinstallprompt', function (event) {
console.log('beforeinstallprompt run .');
event.preventDefault();
deferredPrompt = event;
return false;
});
now for Uninstall:
It can only be removed from the browser
Now my question is here:
Is it possible to create a code such as manual installation (mentioned above) that the user can uninstall the program without the need to use the browser tool?
Thank you all for your answers

Puppeteer and express can not load new data using REST API

I'm using puppeteer to scrape page that has contents that change periodically and use express to present data in rest api.
If I turn on headless chrome to see what is being shown in the browser, the new data is there, but the data is not showing up in get() and http://localhost:3005/api-weather. The normal browser only shows the original data.
const express = require('express');
const server = new express();
const cors = require('cors');
const morgan = require('morgan');
const puppeteer = require('puppeteer');
server.use(morgan('combined'));
server.use(
cors({
allowHeaders: ['sessionId', 'Content-Type'],
exposedHeaders: ['sessionId'],
origin: '*',
methods: 'GET, HEAD, PUT, PATCH, POST, DELETE',
preflightContinue: false
})
);
const WEATHER_URL = 'https://forecast.weather.gov/MapClick.php?lat=40.793588904953985&lon=-73.95738513173298';
const hazard_url2 = `file://C:/Users/xdevtran/Documents/vshome/wc_api/weather-forecast-nohazard.html`;
(async () => {
try {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on("request", request => {
console.log(request.url());
request.continue();
});
await page.goto(hazard_url2, { timeout: 0, waitUntil: 'networkidle0' });
hazard = {
"HazardTitle": "stub",
"Hazardhref": "stub"
}
let forecast = await page.evaluate(() => {
try {
let forecasts = document.querySelectorAll("#detailed-forecast-body.panel-body")[0].children;
let weather = [];
for (var i = 0, element; element = forecasts[i]; i++) {
period = element.querySelector("div.forecast-label").textContent;
forecast = element.querySelector("div.forecast-text").textContent;
weather.push(
{
period,
forecast
}
)
}
return weather;
} catch (err) {
console.log('error in evaluate: ', err);
res.end();
}
}).catch(err => {
console.log('err.message :', err.message);
});
weather = forecast;
server.get('/api-weather', (req, res) => {
try {
res.end(JSON.stringify(weather, null, ' '));
console.log(weather);
} catch (err) {
console.log('failure: ', err);
res.sendStatus(500);
res.end();
return;
}
});
} catch (err) {
console.log('caught error :', err);
}
browser.close();
})();
server.listen(3005, () => {
console.log('http://localhost:3005/api-weather');
});
I've tried several solutions WaitUntil, WaitFor, .then and sleep but nothing seems to work.
I wonder if it has something to do with express get()? I'm using res.end() instead of res.send() is because the json looks better when I use res.end(). I don't really know the distinction.
I'm also open to using this reload solution. But I received errors and didn't use it.
I also tried waitForNavigation(), but I don't know how it works, either.
Maybe I'm using the wrong search term to find the solution. Could anyone point me in the right direction? Thank you.

How to implement spinner with loading controller in ionic 3?

I want to implement spinner with loading controller in ionic3 . I have implemented simple loading controller . how to do it? thanks in advance.
My current loader
I want something like this
presentLoadingCustom() {
let loading = this.loadingCtrl.create({
spinner: 'hide',
content: `<img src="assets/img/gif.gif" />`,
duration: 5000
});
loading.onDidDismiss(() => {
console.log('Dismissed loading');
});
loading.present();
}
inside image tag give some gif image and it works fine i have tested it
Output
Ionic 2&3 has a built in service for blocking UI and giving visual feedback to users when the app is executing some time consuming activity on background such as loading data from a remote database .
You simply use the LoadingController which is available from ionic-angular module
So start by importing LadingController
import { LoadingController } from 'ionic-angular';
Then create a property and inject it on the class constructor
export class LoginPage {
loading: any;
constructor(public loadingController:LoadingController){...}
}
and create loading indicator in method from where requesting the data
login() {
this.loading = this.loadingController.create({ content: "Logging in ,please wait..." });
this.loading.present();
this.errors = "";
//api service call
this.authService.postData(this.userData, 'api/account/login').then((result) => {
this.responseData = result;
if (result != null) {
this.loading.dismissAll();
//console.log(result);
this.common.setLocalData(DataKey.User.toString(), result);
this.navCtrl.push(TabsPage);
}
else {
this.loading.dismissAll();
this.errors = "Nope, Try Again";
}
}, (err) => {
this.loading.dismissAll();
this.errors = "Nope, Try Again";
// Error log
});
}
When you are successfully logged in the method dismissAll() hides the loading indicator so you can continue interacting with your app normally.

How to always check if the Location service is enabled in Ionic 2?

I am trying to figure out how to always check if the location service is enabled. By always I mean like a real-time checker. What I have now is only in one view. I am checking when the user signs in - if the location service is enabled, he signs in. However, if it's unenabled then an Alert dialog appears:
This is my function that checks if it's enabled:
checkLocation() {
this.diagnostic.isLocationEnabled().then(
(isAvailable) => {
console.log('Is available? ' + isAvailable);
if (isAvailable) {
this.navCtrl.setRoot(UserTypePage);
} else {
alert('Please turn on the location service');
if (this.autoLogin) {
this.autoLogin();
}
}
}).catch((e) => {
console.log(e);
alert(JSON.stringify(e));
});
}
I call this function when a user tries to sign in.
Example with Facebook sign in:
facebookLogin(): void {
this.global = ShareService.getInstance();
this.subscriptions.push(this.authProvider.loginWithFacebook().subscribe((user) => {
this.loading.dismiss().then(() => {
this.global.setUserName(user.displayName);
this.global.setProfilePicture(user.photoURL);
this.global.setUserId(this.authProvider.currentUserId);
this.tokenstore();
this.checkLocation(); //HERE
})
}, error => {
this.loading.dismiss().then(() => {
let alert = this.alertCtrl.create({
message: error.message,
buttons: [
{
text: "Ok",
role: 'cancel'
}
]
});
alert.present();
});
}, (err) => {
console.error("error: " + JSON.stringify(err));
}));
this.loading = this.loadingCtrl.create({
content: 'Signing in...'
});
this.loading.present();
}
I want this function to work in the whole application not just in the login view. How do I do that?
This is a classic scenario where Angular Dependency Injection will help you to reuse an existing method across components/views.
You can create a LocationCommonService in your application and define the method to check if Location service is enabled.
Now inject LocationCommonService in all the components where there is a need to call the required function.

Protractor & Cucumberjs after hook doesn't work as expected

I have written a basic after hook in cucumberjs for some reason , it is not working as expected.It is supposed to attached screenshot and write browser console log , when scenario fails. But it attaches the screen shot after the feature in html report and prints the browser console log at after in between the second scenarioenter image description here.Any clue what's wrong??
this.After(function(scenario, callback) {
if (scenario.isFailed()) {
global.browser.takeScreenshot().then(function(base64png) {
var decodedImage = new Buffer(base64png,'base64').toString('binary');
scenario.attach(decodedImage, 'image/png');
});
global.browser.manage().logs().get('browser').then(function (browserlog){
browserlog.forEach(function (log) {
if (log.level.value > 900) {
console.error(log.message.substring(log.message.indexOf('Error'),log.message.indexOf('\n')))
}
})
});
callback();
} else {
callback();
}
});
According to the cucumberjs github page https://github.com/cucumber/cucumber-js#attachments
Images and other binary data can be attached using a stream.Readable. In that case, passing a callback to attach() becomes mandatory:
You could split the single after hook into two separate hooks:
this.After(function(scenario, next) {
browser.takeScreenshot().then(function(png) {
var decodedImage = new Buffer(png, 'base64').toString('binary');
scenario.attach(decodedImage, 'image/png', next);
}, function(err) {
next(err);
});
});
this.After(function(scenario, next) {
global.browser.manage().logs().get('browser').then(function (browserlog){
browserlog.forEach(function (log) {
if (log.level.value > 900) {
console.error(log.message.substring(log.message.indexOf('Error'),log.message.indexOf('\n')))
}
});
});
});