Ionic2 Loading component error

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)

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();
                }
            });

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.

Problem solved. Thanks @iignatov

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?

1 Like

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

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!

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

1 Like

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

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.

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.

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)
  }

image

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.

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.

1 Like

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.

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;