My problem is quite simple : I try to implement a component in modal, but when I try to add SwipeToClose, it's not working (The modal stay static even if I try to swipe down) ...
I'm really confused, but I've create a Stackblitz to show you my issue in detail, maybe I miss something important ... : https://stackblitz.com/edit/ionic-angular-v5-u4wmun
My component :
import { Component, Injectable } from '#angular/core';
import { NavController, ModalController } from '#ionic/angular';
import { ModalComponent } from './modal/modal.component';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myModal:any;
constructor(
public modalController: ModalController
) {
}
async presentModal() {
this.myModal = await this.modalController.create({
component: ModalComponent,
swipeToClose: true,
backdropDismiss: true
});
return await this.myModal.present();
}
}
Thanks to your time !
PS : I try to use it in iOS only, I've already try on my iOS device and it's doesn't work too ...
swipe to close is only available for modals in ios mode(currently ionic v5). So, specify the mode of your modal to be ios
this.myModal = await this.modalController.create({
component: ModalComponent,
swipeToClose: true,
mode: 'ios',
backdropDismiss: true
});
SwipeToClose Gesture only works on IOS mode and could be applied on card modals and will be deprecated by next release. If you apply following method to IonContent element or first element in body, it detects swipeDown gesture and kinda solves that issue and works with all modes.
constructor(public gestureCtrl: GestureController) { }
swipeDownToCloseModal = (elm: HTMLElement)=>{
const swipeGesture: Gesture = this.gestureCtrl.create({
el:elm,
threshold:1,
maxAngle:95,
gestureName:'swipeGesture',
onEnd:e=>{
if(e.velocityY>0.15 && e.deltaY>100 && elm.getBoundingClientRect().y===0){
this.modal.dismiss(); //change
}
}
});
swipeGesture.enable(true);
};
Related
How to Hide Keyboard in ionic3?
We have a problem with ionic 3 apps during testing in iPhone. After fillup Payment Gateway information (which is launched in iFrame), Whenever we go to the back page using the back button, Keyboard is not Hiding.
We used cordova-plugin-ionic-keyboard and use Keyboard.hide() method. But didn't work.
Using Keyboard plugin for Cordova:
import { Keyboard } from '#ionic-native/keyboard/ngx';
...
constructor(private keyboard: Keyboard) { }
...
this.keyboard.show();
this.keyboard.hide();
Or if you are using Capacitor (recommended):
import { Plugins, KeyboardInfo } from '#capacitor/core';
const { Keyboard } = Plugins;
...
Keyboard.show();
Keyboard.hide();
Try this
import { Keyboard } from '#ionic-native/keyboard';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public navCtrl: NavController, public keyboard : Keyboard) {
}
}
and then on back button use this
this.keyboard.close()
The ionViewDidLoad function seem to get called twice, which is causing multiple views being created of AddressPage. I have debugged this and it looks like whenever data is updated the new instance of view gets created. This behaviour seems to happen only when I use fireabse to save the address. If I comment out the code to save the address new view is not created and app navigates to previous screen.
Any way to avoid this?
I have tried ViewCotnroller.dismiss() and NavController.pop() inside saveAddress method but non seem to avoid creation of new view.
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = HomePage;
constructor(platform: Platform, statusBar: StatusBar) {
platform.ready().then(() => {
statusBar.styleDefault();
statusBar.backgroundColorByHexString('#1572b5');
});
}
}
Home Page
import {NavController } from 'ionic-angular';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public navCtrl: NavController, public firebaseProvider:
FirebaseProvider) {
}
//navigate to different view
navigate(){
this.navCtrl.push(AddressPage, {address:newAddress});
}
}
Address Page
import {NavController } from 'ionic-angular';
#Component({
selector: 'page-address',
templateUrl: 'address.html'
})
export class AddressPage {
constructor(public navCtrl: NavController, public firebaseProvider:
FirebaseProvider, private navParams: NavParams) {
this.addressKey = this.navParams.get('key');
}
ionViewDidEnter(){
//load some data from server
}
saveAddress(){
//save data to server
this.firebaseProvider.saveAddress(newAddress);
//move back
this.navCtrl.pop();
}
}
Firebase provider that uses AngularFireDatabase
import { Injectable } from '#angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
#Injectable()
export class FirebaseProvider {
constructor(public afd: AngularFireDatabase) { }
saveAddress(address) {
this.afd.list('/addresses').push(address);
}
updateAddress(key,dataToUpdate){
return this.afd.list('addresses').update(key,dataToUpdate);
}
}
I have also tried this but it has the same issue.
this.firebaseProvider.saveAddress(newAddress).then(result => {
// loadingSpinner.dismiss();
this.navCtrl.pop();
});
this.firebaseProvider.updateAddress(this.addressKey, updateItems)
.then(() => {
// loadingSpinner.dismiss();
this.navCtrl.pop()
});
The HTML of save button
<button type="button" ion-button full color="primary-blue" (click)='saveAddress()'>Save</button>
Looks like unsubscribing to the subscribers fixes the issue. The HomePage view had subscribers which were not unsubscribed. I added the Observable Subscriptions into the array and unsubscribed as per code below.
ionViewWillLeave(){
this.subscriptions.forEach(item=>{
item.unsubscribe();
});
}
the push method returs a promise with the result of the action. I would change the save method like this:
saveAddress(address) {
return this.afd.list('/addresses').push(address);
}
Then in the controller I’d change it in this way:
saveAddress(){
//save data to serve
this.firebaseProvider.saveAddress(newAddress).then(result => {
//do yours validations
this.navCtrl.pop();
});
}
With thos you tide up the navigation of the page to the result of the Firebase execution. Give it a try to this approach and let me know if it didn’t work, anyway I would use oninit to load data only once as I guess you wanna do it rather than ionViewDidEnter.
I am trying to implement geolocation on my new project. I have installed the below plugins and added them in app.module.ts
ionic cordova plugin add cordova-plugin-mauron85-background-geolocation
npm install --save #ionic-native/background-geolocation
I am following this tutorial but getting error in home.ts. Below is my home.ts code.
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { BackgroundGeolocation, BackgroundGeolocationConfig, BackgroundGeolocationResponse } from '#ionic-native/background-geolocation';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(private backgroundGeolocation: BackgroundGeolocation,public navCtrl: NavController) {
}
const config: BackgroundGeolocationConfig = {
desiredAccuracy: 10,
stationaryRadius: 20,
distanceFilter: 30,
debug: true, // enable this hear sounds for background-geolocation life-cycle.
stopOnTerminate: false, // enable this to clear background location settings when the app terminates
};
this.backgroundGeolocation.configure(config)
.subscribe((location: BackgroundGeolocationResponse) => {
console.log(location);
// IMPORTANT: You must execute the finish method here to inform the native plugin that you're finished,
// and the background-task may be completed. You must do this regardless if your HTTP request is successful or not.
// IF YOU DON'T, ios will CRASH YOUR APP for spending too much time in the background.
//this.backgroundGeolocation.finish(); // FOR IOS ONLY
});
// start recording location
this.backgroundGeolocation.start();
// If you wish to turn OFF background-tracking, call the #stop method.
this.backgroundGeolocation.stop();
}
Error is on this line: this.backgroundGeolocation.configure(config). On this it's saying;
[ts] Unexpected token. A constructor, method, accessor, or property was expected.
And on config it's saying:
[ts] Cannot find name 'config'
As #SurajRao was pointing in his comment, you need to move your code either inside the class constructor or wrap it in a method.
Here is your component with the code placed inside the constructor:
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { BackgroundGeolocation, BackgroundGeolocationConfig, BackgroundGeolocationResponse } from '#ionic-native/background-geolocation';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(private backgroundGeolocation: BackgroundGeolocation,public navCtrl: NavController) {
const config: BackgroundGeolocationConfig = {
desiredAccuracy: 10,
stationaryRadius: 20,
distanceFilter: 30,
debug: true,
stopOnTerminate: false,
};
this.backgroundGeolocation.configure(config)
.subscribe((location: BackgroundGeolocationResponse) => {
console.log(location);
});
this.backgroundGeolocation.start();
this.backgroundGeolocation.stop();
}
}
Read more about JavaScript classes on MDN.
In an Ionic project i am using the code below to load a document collection from Firestore with the AngularFirestore wrappers.
Now that the content starts loading when the view was initialized i'm experiencing a delay by about 4-8 seconds until the firestore fetched data renders in my list-view, which is very very bad for the overall userexperience.
with the code below i'm able to show a loading spinner when the content starts loading bit i need it to stop showing the loader.
I have no clue how to trigger that event? Any help would be appreciated
thank you very much
import { City } from './../../model/City';
import { Component, AfterViewInit } from '#angular/core';
import { NavController, IonicPage, LoadingController } from 'ionic-angular';
import { AngularFirestore, AngularFirestoreCollection } from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';
#IonicPage()
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage implements AfterViewInit {
citiesRef: AngularFirestoreCollection<City>
cities: Observable<City[]>;
loading = this.loadingCtrl.create({
content: 'Loading Regions...'
});
constructor(private loadingCtrl: LoadingController, private afs: AngularFirestore, public navCtrl: NavController) {
}
ngAfterViewInit(){
this.loading.present().then(()=>{
this.citiesRef = this.afs.collection<City>('regions', ref => ref.orderBy('name'));
this.cities = this.citiesRef.valueChanges();
})
}
}
Well, what I did was I subscribe to the this.cities. It worked in my case. The idea is it will fire loading.dismiss() once it is able to subscribe. Hope that helps
let loading = this.loadingCtrl.create({
content: 'Please wait...'
});
loading.present();
this.citiesRef=this.afs.collection('cities');
this.cities=this.citiesRef.valueChanges();
this.cities.subscribe(_=>{
loading.dismiss();
})
After going through Clear History and Reload Page on Login/Logout Using Ionic Framework
I want to know same question, but for ionic2 using typescript.
On login and logout I need reload the app.ts, because there are classes that run libraries on construct.
it would be basically redirect to home and reload.
Found this answer here, (please note especially the line this.navCtrl.setRoot(this.navCtrl.getActive().component); which is by far the simplest solution that I've come across to reload present page for Ionic 2 & 3 and later versions of Angular (mine is 4), so credit due accordingly:
RELOAD CURRENT PAGE
import { Component } from '#angular/core';
import { NavController, ModalController} from 'ionic-angular';
#Component({
selector: 'page-example',
templateUrl: 'example.html'
})
export class ExamplePage {
public someVar: any;
constructor(public navCtrl: NavController, private modalCtrl: ModalController) {
}
refreshPage() {
this.navCtrl.setRoot(this.navCtrl.getActive().component);
}
}
If you want to RELOAD A DIFFERENT PAGE please use the following (note this.navCtrl.setRoot(HomePage);:
import { Component } from '#angular/core';
import { NavController, ModalController} from 'ionic-angular';
import { HomePage } from'../home/home';
#Component({
selector: 'page-example',
templateUrl: 'example.html'
})
export class ExamplePage {
public someVar: any;
constructor(public navCtrl: NavController, private modalCtrl: ModalController) {
}
directToNewPage() {
this.navCtrl.setRoot(HomePage);
}
}
Ionic 1
I haven't used Ionic 2 but currently i m using Ionic 1.2 and if they are still using ui-router than you can use reload: true in ui-sref
or you can add below code to your logout controller
$state.transitionTo($state.current, $stateParams, {
reload: true,
inherit: false,
notify: true
});
Angular 2
Use
$window.location.reload();
or
location.reload();
You have to implement the CanReuse interface, and override the routerCanReuse to return false. Then, try calling router.renavigate().
Your component should look like this:
class MyComponent implements CanReuse {
// your code here...
routerCanReuse(next: ComponentInstruction, prev: ComponentInstruction) {
return false;
}
}
And then, when you perform login/logout, call:
// navigate to home
router.renavigate()
This is a hack, but it works.
Wrap the logic that follows your template adjustment in a setTimeout and that gives the browser a moment to do the refresh:
/* my code which adjusts the ng 2 html template in some way */
setTimeout(function() {
/* processing which follows the template change */
}, 100);
For ionic 2 it works for me when you force page reload by triggering fireWillEnter on a view controller
viewController.fireWillEnter();
Here is what worked for me to refresh only current page-
I am trying to call refreshMe function when I call onDelete from my view page,
See how my page.ts file looks-
export class MyPage {
lines of code goes here like
public arr1: any;
public arr2: any;
public constructor(private nav: NavController, navParams: NavParams) {
this.nav = nav;
this.arr1 = [];
this.arr2 = [];
// console.log("hey array");
}
onDelete() {
perform this set of tasks...
...
...
refreshMe()
}
refreshMe() {
this.nav.setRoot(MyPage);
}
}
This is just refreshing only current page.
We can also call this function from view if we need as--
<ion-col width-60 offset-30 (click)="refreshMe()">
....
....
</ion-col>
I personally use these three lines to totally refresh a component
let active = this.navCtrl.getActive(); // or getByIndex(int) if you know it
this.navCtrl.remove(active.index);
this.navCtrl.push(active.component);
You can use the ionViewWillLeave() to display your splashscreen while component is reloading and then hide it with ionViewDidEnter() once its loaded.
Hope it helps