I'm setting up a new alert in Ionic 4 - blank type:angular project.
It's basic alert but I get an error occured running of my project.
Error
Property 'present' does not exist on type 'Promise'. Did you forget to use 'await'?
My create the same code as in documentation. Links:https://ionicframework.com/docs/api/components/alert/AlertController/
My code:
import { AuthenticationService } from './../../services/authentication.service';
import { Component, OnInit } from '#angular/core';
import { AlertController, LoadingController, NavController } from
'#ionic/angular';
#Component({
selector: 'app-register',
templateUrl: './register.page.html',
styleUrls: ['./register.page.scss'],
})
export class RegisterPage implements OnInit {
createSuccess = false;
registerCredentials = { email: '', password: '' };
constructor(
private nav: NavController,
private auth: AuthenticationService,
private alertCtrl: AlertController) { }
ngOnInit() {
}
presentAlert() {
const alert = this.alertCtrl.create({
message: 'Low battery',
subHeader: '10% of battery remaining',
buttons: ['Dismiss']
});
alert.present(); <--- error Property 'present' does not exist on type 'Promise<HTMLIonAlertElement>'. Did you forget to use 'await'?
}
public register() {
this.auth.register(this.registerCredentials).subscribe(success => {
if (success) {
this.createSuccess = true;
this.showPopup('Success', 'Account created.');
} else {
this.showPopup('Error', 'Problem creating account.');
}
},
error => {
this.showPopup('Error', error);
});
}
showPopup function that shoulbe be working..
showPopup(title, text) {
let alert = this.alertCtrl.create({
message: title,
subHeader: text,
buttons: [
{
text: 'OK'
}
]
});
alert.present(); <-- the same error
}
The documentation you are using refers to ionic 3
As you are using Ionic 4, you need to refer to the current Ionic 4 docs and this.
this.alertController.create({...})
returns promise of the object as the error specifies.
Your code needs to be:
async presentAlert() {
const alert = await this.alertCtrl.create({
message: 'Low battery',
subHeader: '10% of battery remaining',
buttons: ['Dismiss']
});
await alert.present();
}
Since create method of alert controller return promise that's why you can not use present method directly. What you need to do is "use then" and call present method like below-
presentAlert() {
const alert = this.alertCtrl.create({
message: 'Low battery',
subHeader: '10% of battery remaining',
buttons: ['Dismiss']}).then(alert=> alert.present());
}
Hope it will helpful :).
I have resolved with this solution ..
Write alert.present() like this (await alert).present()
async presentAlert() {
let alert = this.alertCtrl.create({
subHeader: 'Low battery',
message: 'This is an alert message.',
buttons: ['Dismiss']
});
(await alert).present();
}
You have to use async and await. Here is a code sample:
async showAlert () {
const alert = await this.alertCtrl.create({
header: 'Alert',
subHeader: 'Subtitle',
message: 'This is an alert message.',
buttons: ['okay']
});
await alert.present();
};
Related
I am implementing push notification in my Ionic 6 App. I am using #capacitor/push-notifications plugin to manage push notification in my Ionic App.
import { Injectable } from '#angular/core';
import { Capacitor } from '#capacitor/core';
import { PushNotifications } from '#capacitor/push-notifications';
import { Router } from '#angular/router';
#Injectable({
providedIn: 'root',
})
export class FcmService {
constructor(private router: Router) {}
initPush() {
const fcmtoken = localStorage.getItem('fcmtoken');
if (Capacitor.platform !== 'web' && !fcmtoken) {
this.registerNotifications();
}
}
registerNotifications = async () => {
let permStatus = await PushNotifications.checkPermissions();
if (permStatus.receive === 'prompt') {
permStatus = await PushNotifications.requestPermissions();
}
if (permStatus.receive !== 'granted') {
throw new Error('User denied permissions!');
}
await PushNotifications.register();
await PushNotifications.addListener('registration', token => {
console.info('Registration token: ', token.value);
localStorage.setItem('fcmtoken', token.value);
});
await PushNotifications.addListener('registrationError', err => {
console.error('Registration error: ', err.error);
});
await PushNotifications.addListener('pushNotificationReceived', notification => {
console.log('Push notification received: ', notification);
});
await PushNotifications.addListener('pushNotificationActionPerformed', notification => {
alert(JSON.stringify(notification));
console.log('Push notification action performed', notification.actionId, notification.inputValue);
});
}
getDeliveredNotifications = async () => {
const notificationList = await PushNotifications.getDeliveredNotifications();
console.log('delivered notifications', notificationList);
}
}
I am calling the initPush() from AppComponent and i am receiving notification in my app. But when i tap on that notification nothing happens. pushNotificationActionPerformed event is not getting triggered. Am i missing some configuration. I am using it in Android app.
Please help if someone has implemented it.
My Ionic 5 application has the following 3 pages with the navigation path
HomePage -> UserPage (with canDeactivate guard) -> SharePage
UserPage canDeactivate method:
canDeactivate() {
const alert = await this.alertCtrl.create({
message: 'Do you want to go back?',
buttons: [
{
text: 'No',
role: 'cancel',
handler: () => { }
},
{
text: 'Yes',
handler: () => { }
}
]
});
await alert.present();
let data = await alert.onDidDismiss();
if (data.role == 'cancel') {
return false;
} else {
return true;
}
}
In UserPage, on the back button when I choose 'Yes' it works fine and takes me back to HomePage.
When I choose 'No', the canDeactivate method returns false and UserPage remains open.
Then I click on the Share button to navigate to SharePage.
The share page becomes the root page and it does not have the back button
I have a 1 service and 1 component and I'd like to keep the action sheet functionality in the service and then pass the result to the component. For some reason I cannot access the returned value. Here are the docs to the actionsheetcontroller.
// photo.service
async selectImageSheet() {
const actionSheet = await this.actionSheetController.create({
header: "Select Image source",
buttons: [
{
text: 'Load from Library',
handler: () => {
this.imageSource = this.camera.PictureSourceType.PHOTOLIBRARY
return this.imageSource
}
},
{
text: 'Use Camera',
handler: () => {
this.imageSource = this.camera.PictureSourceType.CAMERA
return this.imageSource
}
},
{
text: 'Cancel',
role: 'cancel',
}
]
})
}
And in my component I do the following:
//component
selectImage() {
this.photo.selectImageSheet().then(() => console.log(this.photo.imageSource))
console.log(this.photo.imageSource)
}
Neither of the console.logs appear in the component. I've tried returning a promise with no luck.
you need to use onDismiss - check the doc - https://ionicframework.com/docs/api/action-sheet
const actionSheet = await actionSheetController.create({
header: "Sheet Header",
buttons: [ ]
});
await actionSheet.present();
let result = await actionSheet.onDidDismiss();
console.log(results)
I created a simple function of creating a loading like this
async presentLoading() {
const loading = await this.loadingController.create({
message: 'Please Wait...',
});
await loading.present();
}
And i am closing the loader when the data is fetch like this
getUserData(){
console.log(this.userID);
this.api.getCompanyEmploye(this.userID).subscribe(res => {
this.loadingController.dismiss(); //closing here
console.log(res);
this.user = res.records[0];
this.familyMembers = res.records[0].family_members;
});
}
I am calling both function in constructor
constructor(public loadingController: LoadingController){
this.presentLoading();
this.getUserData();
}
Its showing error of ERROR Error: Uncaught (in promise): overlay does not exist
The issue is that your API call responds sooner than the loading controller gets instantiated. Instead of parallel calls, you should try to serialize those this way:
Make your presentLoading method to return Promise:
async presentLoading() {
const loading = await this.loadingController.create({
message: 'Please Wait...',
});
return loading.present();
}
Now you can call it this way:
getUserData(){
this.presentLoading().then(()=>{
this.api.getCompanyEmploye(this.userID).subscribe(res => {
this.loadingController.dismiss(); //closing here
console.log(res);
this.user = res.records[0];
this.familyMembers = res.records[0].family_members;
});
})
}
And in your constructor you need only to call for the API
for me, the issue is simply because I don't have .catch() for the promise. As#Sergey suggested, this is because the loader is not ready when you calling the ionic loader
this.loadingController.dismiss()
.then(async () => {
await this.setStorageForLocalData(data);
})
.catch(console.error);
where .catch() will dismiss the error
I am making a simple crud with Ionic4, everything is working fine. When i update my record via put call and navigate back to detail of the record to see updated values it shows old values. My update and navigate code is:
async updateClient() {
await this.api.updateClient(this.route.snapshot.paramMap.get('id'), this.clientForm.value)
.subscribe(res => {
let id = res['_id'];
this.router.navigate(['/client/detail', id]);
}, (err) => {
console.log(err);
});
}
And detail page code is:
import { Component, OnInit } from '#angular/core';
import { LoadingController } from '#ionic/angular';
import { RestApiService } from '../../rest-api.service';
import { ActivatedRoute, Router } from '#angular/router';
import {Location} from '#angular/common';
#Component({
selector: 'app-detail',
templateUrl: './detail.page.html',
styleUrls: ['./detail.page.scss'],
})
export class DetailPage implements OnInit {
client: any = {};
constructor(public api: RestApiService,
public loadingController: LoadingController,
public route: ActivatedRoute,
public router: Router,
private location: Location) {}
async getClient() {
console.log('in getClient');
const loading = await this.loadingController.create({
});
await loading.present();
await this.api.getClientById(this.route.snapshot.paramMap.get('id'))
.subscribe(res => {
console.log(res);
this.client = res;
loading.dismiss();
}, err => {
console.log(err);
loading.dismiss();
});
}
ngOnInit() {
this.getClient();
}
Try to call this.getClient() method in ionViewWillEnter() method as below :
ionViewWillEnter(){
this.getClient();
}
It will call your this.getClient() method every time when you enter in the page whether it is loaded or not.