Ionic2 Loading component error


#1

Hi all,

I am trying to use the Loading component but I have problem trying to manually dismiss the Loading dialog.

LoginPage is a Modal

import {IonicApp, Page, NavController, ViewController, Loading} from 'ionic-angular';
import {User} from '../../providers/user';
import {DashboardPage} from '../dashboard/dashboard';

@Page({
	templateUrl: 'build/pages/login/login.html'
})
export class LoginPage {
	static get parameters() {
		return [[NavController], [User], [ViewController]];
	}

	constructor(nav, user, viewCtrl) {
		this.nav = nav;
		this.user = user;
		this.viewCtrl = viewCtrl;

		// Loading component
		this.loading = Loading.create({
			content: "Authenticating. . ."
		});

		this.login = {};
		this.submitted = false;
	}

	onLogin(form) {
		this.submitted = true;

		if (form.valid) {
			this.nav.present(this.loading);
			if (this.user.login(this.login.username, this.login.password)) {
				//this.loading.dismiss();
				this.viewCtrl.dismiss();
				this.nav.setRoot(DashboardPage);
			}
			else {
				this.loading.dismiss(); // << this is giving problems.
			}
		}
	}

	dismiss(data) {
		// using the injected ViewController this page
		// can "dismiss" itself and pass back data
		this.viewCtrl.dismiss(data);
	}
}

LoginPage html

<ion-navbar *navbar>
	<ion-buttons start>
		<button (click)="dismiss()"><ion-icon ios="ios-close"></ion-icon></button>
	</ion-buttons>
	<ion-title>Sign In</ion-title>
	<ion-buttons end>
		<button (click)="onLogin(loginForm)">Login</button>
	</ion-buttons>
</ion-navbar>

<ion-content>

	<ion-list>
		<form #loginForm="ngForm" novalidate>
			<p class="text first">Use this email address to sign in</p>
			<ion-item>
				<input class="text-input" [(ngModel)]="login.username" placeholder="email address" ngControl="username" type="text" #username="ngForm" required autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false">
			</ion-item>
			<p [hidden]="username.valid || submitted == false" danger padding-left>
				Username is required
			</p>

			<p class="text second">Use this password to sign in</p>
			<ion-item>
				<input class="text-input" [(ngModel)]="login.password" placeholder="password" ngControl="password" type="password" #password="ngForm" required autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false">
			</ion-item>
			<p [hidden]="password.valid || submitted == false" danger padding-left>
				Password is required
			</p>

		</form>
	</ion-list>

</ion-content>

Error

[Error] EXCEPTION: Error during evaluation of "click"
	logError (app.bundle.js:31475)
	logGroup (app.bundle.js:31485)
	call (app.bundle.js:29225)
	(anonymous function) (app.bundle.js:13947)
	(anonymous function) (app.bundle.js:28724)
	__tryOrUnsub (app.bundle.js:73914)
	next (app.bundle.js:73863)
	_next (app.bundle.js:73822)
	next (app.bundle.js:73799)
	_finalNext (app.bundle.js:73674)
	_next (app.bundle.js:73666)
	next (app.bundle.js:73623)
	emit (app.bundle.js:28713)
	onError (app.bundle.js:28400)
	onHandleError (app.bundle.js:28584)
	handleError (angular2-polyfills.js:394)
	runGuarded (angular2-polyfills.js:300)
	runInner (app.bundle.js:28594:82)
	run (app.bundle.js:28501)
	outsideHandler (app.bundle.js:32717)
	invokeTask (angular2-polyfills.js:423)
	runTask (angular2-polyfills.js:320)
	invoke (angular2-polyfills.js:490)
	dispatchEvent
	touchEnd (app.bundle.js:55874)
	(anonymous function)
[Error] ORIGINAL EXCEPTION: TypeError: undefined is not an object (evaluating 'leavingView.pageRef().nativeElement')
	logError (app.bundle.js:31475)
	call (app.bundle.js:29234)
	(anonymous function) (app.bundle.js:13947)
	(anonymous function) (app.bundle.js:28724)
	__tryOrUnsub (app.bundle.js:73914)
	next (app.bundle.js:73863)
	_next (app.bundle.js:73822)
	next (app.bundle.js:73799)
	_finalNext (app.bundle.js:73674)
	_next (app.bundle.js:73666)
	next (app.bundle.js:73623)
	emit (app.bundle.js:28713)
	onError (app.bundle.js:28400)
	onHandleError (app.bundle.js:28584)
	handleError (angular2-polyfills.js:394)
	runGuarded (angular2-polyfills.js:300)
	runInner (app.bundle.js:28594:82)
	run (app.bundle.js:28501)
	outsideHandler (app.bundle.js:32717)
	invokeTask (angular2-polyfills.js:423)
	runTask (angular2-polyfills.js:320)
	invoke (angular2-polyfills.js:490)
	dispatchEvent
	touchEnd (app.bundle.js:55874)
	(anonymous function)
[Error] ORIGINAL STACKTRACE:
	logError (app.bundle.js:31475)
	call (app.bundle.js:29237)
	(anonymous function) (app.bundle.js:13947)
	(anonymous function) (app.bundle.js:28724)
	__tryOrUnsub (app.bundle.js:73914)
	next (app.bundle.js:73863)
	_next (app.bundle.js:73822)
	next (app.bundle.js:73799)
	_finalNext (app.bundle.js:73674)
	_next (app.bundle.js:73666)
	next (app.bundle.js:73623)
	emit (app.bundle.js:28713)
	onError (app.bundle.js:28400)
	onHandleError (app.bundle.js:28584)
	handleError (angular2-polyfills.js:394)
	runGuarded (angular2-polyfills.js:300)
	runInner (app.bundle.js:28594:82)
	run (app.bundle.js:28501)
	outsideHandler (app.bundle.js:32717)
	invokeTask (angular2-polyfills.js:423)
	runTask (angular2-polyfills.js:320)
	invoke (angular2-polyfills.js:490)
	dispatchEvent
	touchEnd (app.bundle.js:55874)
	(anonymous function)
[Error] LoadingPopOut@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:42745:40
createTransition@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:62742:35
file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:45238:74
invoke@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/angular2-polyfills.js:390:34
run@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/angular2-polyfills.js:283:50
runOuter@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:28596:74
runOutsideAngular@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:28514:88
_beforeTrans@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:45228:37
_postRender@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:45210:26
_render@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:45126:29
_transition@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:45098:21
remove@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:44959:29
dismiss@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:46551:32
onLogin@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:472:26
handleEventInternal
handleEvent@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:14300:48
triggerEventHandlers@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:24129:47

file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:32639:48
file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:32717:93
invoke@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/angular2-polyfills.js:390:34
onInvoke@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:28563:47
invoke@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/angular2-polyfills.js:389:43
runGuarded@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/angular2-polyfills.js:297:54
runInner@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:28594:81
run@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:28501:74
outsideHandler@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:32717:64
invokeTask@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/angular2-polyfills.js:423:43
runTask@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/angular2-polyfills.js:320:58
invoke@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/angular2-polyfills.js:490:41
dispatchEvent@[native code]
touchEnd@file:///Users/shawnang/Library/Developer/CoreSimulator/Devices/05D02343-6E70-4EB1-94F1-88011A0C2E7A/data/Containers/Bundle/Application/1EBD5207-9521-43C6-AE2D-D43D18CBED90/SAM.app/www/build/js/app.bundle.js:55874:44
[native code]
	logError (app.bundle.js:31475)
	call (app.bundle.js:29238)
	(anonymous function) (app.bundle.js:13947)
	(anonymous function) (app.bundle.js:28724)
	__tryOrUnsub (app.bundle.js:73914)
	next (app.bundle.js:73863)
	_next (app.bundle.js:73822)
	next (app.bundle.js:73799)
	_finalNext (app.bundle.js:73674)
	_next (app.bundle.js:73666)
	next (app.bundle.js:73623)
	emit (app.bundle.js:28713)
	onError (app.bundle.js:28400)
	onHandleError (app.bundle.js:28584)
	handleError (angular2-polyfills.js:394)
	runGuarded (angular2-polyfills.js:300)
	runInner (app.bundle.js:28594:82)
	run (app.bundle.js:28501)
	outsideHandler (app.bundle.js:32717)
	invokeTask (angular2-polyfills.js:423)
	runTask (angular2-polyfills.js:320)
	invoke (angular2-polyfills.js:490)
	dispatchEvent
	touchEnd (app.bundle.js:55874)
	(anonymous function)

#2

There’s an open issue about this:

As a workaround try the suggestion in the linked post:

In your case you should update your code this way:

           this.nav.present(this.loading).then(() => {
                if (this.user.login(this.login.username, this.login.password)) {
                    //this.loading.dismiss();
                    this.viewCtrl.dismiss();
                    this.nav.setRoot(DashboardPage);
                }
                else {
                    this.loading.dismiss();
                }
            });

#3

Thanks @iignatov that solution is great. It’s just that the document is unclear on that. it just says to use this.loading.dismiss(). I know that Beta can be an excuse reason.


#4

Problem solved. Thanks @iignatov


#5

I try this, but get the following:

import { NavController } from 'ionic-angular';

this.nav.present(this.loading).then(() =...

error:

[ts] Property 'present' does not exist on type 'NavController'.
any

Any ideas?


#6

Things have changed since this thread started. Now you just tell the loader to present itself. See the docs.


#7

Is there any way to manually dismiss Loading (without using timeout)? When I just call the dismiss() method it throws an error saying this.loading.dismiss( ) is not a function!


#8

Maybe you are calling dismiss before the message is presented. loading.present() is a Promise. Don’t call dismiss until the Promise returns.


#9

I thought this wasn’t supposed to be a problem any more. See the discussion in #11119.


#10

I wasn’t aware that bug was fixed. But I still don’t know what happens if you dismiss a Loading you never called. Just returns and does nothing? What if the present() arrives later? I don’t know the answer to that either. At any rate, I wait for the Promise to ack in my own code, before I dismiss. Maybe overkill.


#11

My understanding is that the bug fix made it so there was not a possibility of dismissing things before the presentation was completed, because navigation actions were queued.


#12

I do make sure that Loading is displayed and in its “then” I do my stuff. See the code below where I still get error:

  // Display loading ctrl
  displayLoading() :Promise<any> {
    return this._loading = this._loadingCtrl.create({
      }).present()
  }

  // Dismiss loading ctrl
  dismissLoading() :Promise<any> {
    return this._loading.dismiss();
  }

  registerUser() {
    this.displayLoading()
      .then( () => {
        this._authSrv.createNewUser(this._registerUserForm.value.email, this._registerUserForm.value.password)
          .then( (data) => {
            console.log('User created :' + data);
            this._loading.dismiss()
              .then(() => {
                this._userhSrv.uid = data.uid;
                this._nav.setRoot('UserProfilePage');
              })
              // dimissLoading error
              .catch(console.log)
          })
          // create new user error
          .catch ((error) => {
            this.showAlertToUser(error);
          })
      })
      // displayLoading error
      .catch(console.log)
  }

What is peculiar about this error is that it is shown as an Alert - if you see my code, I am only displaying Alert to user when the new User registration fails. The errors regarding loading controller are supposed to be logged onto console.


#13
this.loading: Loading = this.loadCtrl.create({});
this.loading.present();
this.loading.dismiss();

Not:
this.loading = this.loadCtrl.create({}).present(); // this is a Promise<any> type

You’re assigning a Promise<any> to this.loading, not a Loading type. Reason #500 to strongly type your variables.


#14

In addition to what @AaronSterling said, I think it is never a good idea to store loading components (or alerts, etc) in object properties, for two reasons: it makes it unclear who is responsible for the object, and it encourages double-dismiss and reuse bugs. Always make them only lexically scoped variables.


#15

Thanks Aaron, I now understood why I got the error.

Interestingly though, I did strong type my loading variable and Typescript did not complain when I assigned a Promise to a variable of type Loading

private _loading: Loading;