ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
51.05k stars 13.51k forks source link

Popover Dismiss Causes “RangeError: Maximum call stack size exceeded” on Android Device #6918

Closed ehussain closed 8 years ago

ehussain commented 8 years ago

I am using ionic2 beta8.

I have copied exact usage example from http://ionicframework.com/docs/v2/2.0.0-beta.8/api/components/popover/Popover/#usage

The only thing I changed is I have created separate files for popover.ts popover.html.

After all those changes everything worked fine in browser. But when I test that in Android device, when I try to dismiss the popover (either by calling this.viewController.dismiss() method or clicking on backdrop) I see that UI hung up and nothing happens.

I checked logs in Android Monitoring tool then I found following exception in log.



[INFO:CONSOLE(34947)] "EXCEPTION: Error in ./PopoverCmp class PopoverCmp - inline template:0:14", source: file:///android_asset/www/build/js/app.bundle.js (34947)
[INFO:CONSOLE(34947)] "ORIGINAL EXCEPTION: RangeError: Maximum call stack size exceeded", source: file:///android_asset/www/build/js/app.bundle.js (34947)
[INFO:CONSOLE(34947)] "ORIGINAL STACKTRACE:", source: file:///android_asset/www/build/js/app.bundle.js (34947)
[INFO:CONSOLE(34947)] "RangeError: Maximum call stack size exceeded
    at Object.re.RequireObjectCoercible (file:///android_asset/www/build/js/es6-shim.min.js)
    at Object.re.ToObject (file:///android_asset/www/build/js/es6-shim.min.js:10:4947)
    at Function.keys (file:///android_asset/www/build/js/es6-shim.min.js:10:24378)
    at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:69658:27)
    at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:69665:17)
    at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:69665:17)
    at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:69665:17)
    at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:69665:17)
    at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:69665:17)
    at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:69665:17)", source: file:///android_asset/www/build/js/app.bundle.js (34947)
[INFO:CONSOLE(34947)] "ERROR CONTEXT:", source: file:///android_asset/www/build/js/app.bundle.js (34947)
[INFO:CONSOLE(34947)] "[object Object]", source: file:///android_asset/www/build/js/app.bundle.js (34947)
[INFO:CONSOLE(260)] "Uncaught EXCEPTION: Error in ./PopoverCmp class PopoverCmp - inline template:0:14
ORIGINAL EXCEPTION: RangeError: Maximum call stack size exceeded
ORIGINAL STACKTRACE:
RangeError: Maximum call stack size exceeded
    at Object.re.RequireObjectCoercible (file:///android_asset/www/build/js/es6-shim.min.js)
    at Object.re.ToObject (file:///android_asset/www/build/js/es6-shim.min.js:10:4947)
    at Function.keys (file:///android_asset/www/build/js/es6-shim.min.js:10:24378)
    at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:69658:27)
    at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:69665:17)
    at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:69665:17)
    at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:69665:17)
    at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:69665:17)
    at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:69665:17)
    at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:69665:17)
ERROR CONTEXT:
[object Object]", source: file:///android_asset/www/build/js/zone.js (260)
Debugger is no longer active

Here is code I am using

import { Component } from '@angular/core';
import { App, NavController, NavParams, MenuController, Popover, ViewController } from "ionic-angular";
import { Storage, LocalStorage } from 'ionic-angular';

import { AuthService } from "./../../../services/user/auth";
import { AuthModel } from "./../../../models/user/auth";

@Component({
    template: `
        <ion-list>
            <ion-list-header>Welcome</ion-list-header>
            <button ion-item (click)="onLogout($event)">Logout</button>
        </ion-list>
    `,
    providers: []
})
class PopoverPage {
    private storage;

    constructor(private viewController: ViewController, private nav: NavController, private authService: AuthService, private auth: AuthModel) {
        this.storage = new Storage(LocalStorage);
    }

    close() {
        console.log('On Close Popover');
        this.viewController.dismiss();
    }

    onLogout() {
        this.close();
    }
}

@Component({
    templateUrl: "build/pages/app/dashboard/dashboard.html",
    providers: []
})
export class DashboardNewPage {
    private storage;

    constructor(protected app: App, protected nav: NavController, protected navParams: NavParams, private menu: MenuController, private authService: AuthService, private auth: AuthModel) {
        this.storage = new Storage(LocalStorage);
    }

    public onPopover(event) {
        let popover = Popover.create(PopoverPage);
        this.nav.present(popover, {
            ev: event
        });
    }
}

onPopover function is getting called when nav button is triggered and that markup is present in dashboard.html

This page is rootPage of app and it gets loaded immediately.

Last thing I see in logcat is 'console.log('On Close Popover');' execution. After that it shows exception.

Let me know if I did something wrong here. Please note that this works perfectly fine in browser. But fails in android device.


I guess that the possible cause might be that:

The object that is passed to ToObject() method is too big - this will work on a desktop browser because it has bigger stack so it could handle it but obviously fails on mobile.

It might be an issue with the es6-shim ToObject() method (either a bug or it's not very effective or not optimized) - most desktop browsers should have a native implementation of this method and therefore it works fine but obviously on mobile there's no native implementation yet.

henritoivar commented 8 years ago

Try accessing the specific popover ViewController instance.

let popover = Popover.create(PopoverPage); popover is a ViewController instance which is presented by NavController: this.nav.present(popover, {ev: event });

You can access it like this for example: this.nav.last().dismiss();

jgw96 commented 8 years ago

Hello @ehussain I can't seem to reproduce this issue with either my Nexus 6, Nexus 7 or Moto X 2014. Would you mind posting a plunker or repo I can use to reproduce this issue? Thanks for using Ionic!

iignatov commented 8 years ago

I'm just referencing the related forum discussion for more details: https://forum.ionicframework.com/t/54511

jgw96 commented 8 years ago

Thanks @iignatov

Geoffrey-D commented 8 years ago

Hello,

I have the exact same issue that @ehussain . Everything work fine on browser, but when I run it on my android, I have the following error when I close the Popover :

Uncaught EXCEPTION: Error in ./PopoverCmp class PopoverCmp - inline template:0:14 ORIGINAL EXCEPTION: RangeError: Maximum call stack size exceeded ORIGINAL STACKTRACE: RangeError: Maximum call stack size exceeded at Object () at Object.ES.ToObject (file:///android_asset/www/build/js/app.bundle.js:39130:14) at Function.keys (file:///android_asset/www/build/js/app.bundle.js:40396:36) at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:72972:27) at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:72982:26) at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:72982:26) at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:72982:26) at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:72982:26) at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:72982:26) at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:72982:26) ERROR CONTEXT: [object Object]

The error comes from angular2-polyfills.js :

Zone.prototype.runTask = function (task, applyThis, applyArgs) {
                task.runCount++;
                if (task.zone != this)
                    throw new Error('A task can only be run in the zone which created it! (Creation: ' +
                        task.zone.name + '; Execution: ' + this.name + ')');
                var previousTask = _currentTask;
                _currentTask = task;
                var oldZone = _currentZone;
                _currentZone = this;
                try {
                    if (task.type == 'macroTask' && task.data && !task.data.isPeriodic) {
                        task.cancelFn = null;
                    }
                    try {
                        return this._zoneDelegate.invokeTask(this, task, applyThis, applyArgs);
                    }
                    catch (error) {
                        if (this._zoneDelegate.handleError(this, error)) {
                            throw error; // THIS IS THIS ONE
                        }
                    }
                }
                finally {
                    _currentZone = oldZone;
                    _currentTask = previousTask;
                }
            };

Here is my config in package.json :

 "@angular/common": "^2.0.0-rc.1",
    "@angular/compiler": "^2.0.0-rc.1",
    "@angular/core": "^2.0.0-rc.1",
    "@angular/http": "^2.0.0-rc.1",
    "@angular/platform-browser": "^2.0.0-rc.1",
    "@angular/platform-browser-dynamic": "^2.0.0-rc.1",
    "@angular/router": "^2.0.0-rc.1",
    "es6-shim": "0.35.00",
    "ionic-angular": "2.0.0-beta.8",
    "ionic-native": "^1.1.0",
    "ionicons": "3.0.0",
    "ng2-cordova-oauth": "0.0.4",
    "ng2-translate": "^2.1.0",
    "reflect-metadata": "0.1.2",
    "rxjs": "5.0.0-beta.6",
    "zone.js": "0.6.12"

Can't wait to have a fix :)

EDIT : I tested it with ionic-angular 2.0.0-beta.9 and I still have the issue

jgw96 commented 8 years ago

Hello @Geoffrey-D do you have a minimal example that I can use to test, like a plunker or test repo? Thanks for using Ionic!

Geoffrey-D commented 8 years ago

Hey @jgw96, here is the repo : https://github.com/Geoffrey-D/issue-6918-temp. Everything should be in there (I did it fast). Tell me if you have any issue with it

Geoffrey-D commented 8 years ago

Hey @jgw96, I made an other test, the application of the repo is not working on an low-end phone (Wiko Rainbow : Android OS, v4.4.2 (KitKat) / 1GB RAM / Quad-core 1.3 GHz Cortex-A7) but is working on a Samsung S6. So it seems to be too "heavy" for low-end phone

bea91 commented 8 years ago

Hello @Geoffrey-D same issue on Elephone P7000 android version 5.0, but works fine on Samsung S6, Nexus 6, Nexus 5.

rossmartin commented 8 years ago

I'm having the same issue in beta 9. It happens to me while testing in Chrome and the iOS simulator.

Ionitron commented 8 years ago

Greetings @ehussain!

My sensors indicate a reply was requested, but as we have not received one yet, I am using my robot powers to close this issue. However, if you are still experiencing this issue, please feel free to reopen it by creating a new issue, and include any examples or necessary information.

Thank you for allowing me to assist you.

Ionitron commented 8 years ago

Greetings @ehussain!

My sensors indicate a reply was requested, but as we have not received one yet, I am using my robot powers to close this issue. However, if you are still experiencing this issue, please feel free to reopen it by creating a new issue, and include any examples or necessary information.

Thank you for allowing me to assist you.

tomgallagher commented 8 years ago

You can't close this issue - two other issues have been closed and referenced to this issue, at least 10 people are reporting this problem. Ionitron you don't know what you're doing!

Geoffrey-D commented 8 years ago

I can't agree more. This issue is an important one as it crashes smartphones with low memory, even though it works on recent phones. There is a memory leak that needs to be fixed!

theskhan commented 8 years ago

I am also getting the exact same issue. Ionic Team, please do not close this issue as this is very important one. I have tried all sort of fix, but still couldn't found a way to fix it. (It works perfectly fine in Google Chrome & on a Lumia 550 Windows 10 device with 1 GB RAM).

You can also replicate this issue on a Genymotion Android Emulator:

Genymotion Android Image: Google Nexus 10 - 5.1.0 - API 22, 2560x1600, 320 DPI, Ionic CLI Version: v2.0.0-beta.32

Sample Code: Template:

  <ion-navbar>
      <ion-buttons end="">
        <button class="disable-hover bar-button bar-button-default bar-button-icon-only">
          <span class="button-inner">
            <ion-icon name="search" role="img" class="ion-ios-search" aria-label="search" ng-reflect-name="search"></ion-icon>
          </span>
          <ion-button-effect></ion-button-effect>
        </button>

        <button class="disable-hover bar-button bar-button-default bar-button-icon-only" (click)="more($event)">
          <span class="button-inner">
            <ion-icon name="more" role="img" class="ion-ios-more" aria-label="more" ng-reflect-name="more"></ion-icon>
          </span>
          <ion-button-effect></ion-button-effect>
        </button>
      </ion-buttons>
      <div class="toolbar-content">
        <ion-title>Popular Stations</ion-title>
      </div>
  </ion-navbar>
</ion-header>

Popover Page:

import {Component} from '@angular/core';
import {NavController, ViewController} from 'ionic-angular';

@Component({
  template: '
    <ion-list>
      <ion-list-header>Ionic</ion-list-header>
      <button ion-item (click)="close()">Learn Ionic</button>
      <button ion-item (click)="close()">Documentation</button>
      <button ion-item (click)="close()">Showcase</button>
      <button ion-item (click)="close()">GitHub Repo</button>
    </ion-list>'
})

export class MoreOptionsPage {
  constructor(private viewCtrl: ViewController) {}

  close() {
    this.viewCtrl.dismiss();
  }
}

Displaying the Popover:

more(e){
    let popover = Popover.create(MoreOptionsPage);    
    this.nav.present(popover, {ev: e});
  }

Android Log:

I/chromium( 2112): ORIGINAL STACKTRACE:

I/chromium( 2112): RangeError: Maximum call stack size exceeded

I/chromium( 2112):     at Object (native)

I/chromium( 2112):     at Object.re.ToObject (file:///android_asset/www/build/js/es6-shim.min.js:10:4947)

I/chromium( 2112):     at Function.keys (file:///android_asset/www/build/js/es6-shim.min.js:10:24378)

I/chromium( 2112):     at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:76634:27)

I/chromium( 2112):     at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:76641:17)

I/chromium( 2112):     at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:76641:17)

I/chromium( 2112):     at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:76641:17)

I/chromium( 2112):     at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:76641:17)

I/chromium( 2112):     at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:76641:17)

I/chromium( 2112):     at _baseExtend (file:///android_asset/www/build/js/app.bundle.js:76641:17)

I/chromium( 2112): ERROR CONTEXT:

I/chromium( 2112): [object Object]", source: file:///android_asset/www/build/js/zone.js (260)
henritoivar commented 8 years ago

+1 Using a genymotion Nexus 5 - android 6.0.0 - API 23 emulator.

schlaus commented 8 years ago

+1, testing on a Huawei Honor 6, Android 5.1.1.

thgfrzm commented 8 years ago

+1 using:

No problems in:

workaround:

showFilterPopover(event){
    let popover = this.popoverController.create(SearchFilterPopover);
    popover.present({ ev: null }); // <- pass 'null' to event and adjust the CSS
}
Geoffrey-D commented 8 years ago

Using crosswalk solved the issue for me. For my part, I will use crosswalk in production as I have other issues that crosswalk fixed (the material design animations was also not working without crosswalk). For those that also want to use crosswalk and do https calls, be aware that it will not accept self-signed certificat.

pjsb commented 8 years ago

Same problem here with Galasy S6 when passing data on dismiss.

popover.present({ ev: null }); // <- pass 'null' to event and adjust the CSS did also work for me. @thgfrzm can you post your css ajustments?

thgfrzm commented 8 years ago

hi Jens @pjsb, actually I'm just overwriting the popover-style class. This solution needs some adjustments. Put at the same page.scss that call the popover

.popover-style{
  .popover-content{
    top: 10px !important;
    left: 23% !important;
    transform-origin: right top 0px !important;
  }
}
bea91 commented 8 years ago

Hi @pjsb and @thgfrzm, I think it would be better to set this css adjustments:

.popover-content{ top: 44px !important; margin-left: auto !important; right: 10px !important; transform-origin: right top 0px !important; }

martijnlutgens commented 8 years ago

I am testing my app with some beta testers and at least one of them has reported this problem. I also have it on my iWork8 tablet which is not a low-spec tablet. I am using ionic2 beta11. Please fix this in the beta12 beceaude this is a mayor release blocker for my app.

Geoffrey-D commented 8 years ago

hey @martijnlutgens , be aware that using crosswalk solve this issue, as well as using some css as explained by @bea91.

Cheers

martijnlutgens commented 8 years ago

I know but I didn't want to resort to using crosswalk because I have never used it and that would cost me extra time to figure that out.

I also tried the css but it didn't seem to help. But I found out that I had forgotten to change the event to NULL. The CSS solution from bea91 solved it eventually. Tnx!

Geoffrey-D commented 8 years ago

@martijnlutgens I am glad that it helped you, but be aware that crosswalk can be added in 1 code line and will improve (a lot) performances on Android 4.x and fix many issues (like material design on Android 4.x)

tomgallagher commented 8 years ago

with the proviso that Crosswalk won't work with Ionic Cloud Package

jgw96 commented 8 years ago

Hello all! This has been fixed in the rc.0 release of Ionic 2. We are now using Aot compile which means that we no longer have to dynamically compile templates. Thanks!

chcaru commented 7 years ago

Still happening for me in rc0 when passing an event into PopupController.present options (when testing in Chrome w/ ionic serve).

    "@angular/compiler": "2.0.0",
    "@angular/compiler-cli": "0.6.2",
    "@angular/core": "2.0.0",
    "@angular/forms": "2.0.0",
    "@angular/http": "2.0.0",
    "@angular/platform-browser": "2.0.0",
    "@angular/platform-browser-dynamic": "2.0.0",
    "@angular/platform-server": "2.0.0",
    "@ionic/storage": "1.0.3",
    "adal-angular": "^1.0.12",
    "fs": "0.0.1-security",
    "ionic-angular": "2.0.0-rc.0",
    "ionic-native": "2.0.3",
    "ionicons": "3.0.0",
    "reflect-metadata": "0.1.8",
    "rxjs": "5.0.0-beta.12",
    "zone.js": "0.6.21",
dutchview-shreesha commented 7 years ago

Hi everyone, I am working on ionic2 project.but i am facing one issue IOS like,suppose if we open popover or sidemenu continuesly then next time if we open sidemenu or popover it automatically closes.this happens only in IOS.please suggest.

mbakker96 commented 7 years ago

I've this problem with ion-refresh. I added the code from the documentation but got the error MainPage.html:20 ERROR RangeError: Maximum call stack size exceeded. I receive this error also when I remove all the other stuff on the page.

I get it on all devices. Should I open a new issue for this?

ionitron-bot[bot] commented 6 years ago

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.