Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Context menu does not render after router navigation #1136

Closed
1 of 2 tasks
fernando-almeida opened this issue Jan 8, 2019 · 28 comments · Fixed by #1913
Closed
1 of 2 tasks

Context menu does not render after router navigation #1136

fernando-almeida opened this issue Jan 8, 2019 · 28 comments · Fixed by #1913

Comments

@fernando-almeida
Copy link

Issue type

I'm submitting a ... (check one with "x")

  • bug report
  • feature request

Issue description

Current behavior:
Following an OAuth2 flow similar to the samples, the user context menu in the header component does not drop-down upon click and yields the following stack trace.

main.a72571efe1e9cccd811a.js:69949 ERROR TypeError: Cannot read property 'appendChild' of null
at NbOverlayContainerAdapter.push../node_modules/@nebular/theme/components/cdk/adapter/overlay-container-adapter.js.NbOverlayContainerAdapter._createContainer (main.a72571efe1e9cccd811a.js:105528)
at NbOverlayContainerAdapter.push../node_modules/@angular/cdk/esm5/overlay.es5.js.OverlayContainer.getContainerElement (main.a72571efe1e9cccd811a.js:11222)
at NbOverlay.push../node_modules/@nebular/theme/components/cdk/overlay/mapping.js.NbOverlay.createHostElement (main.a72571efe1e9cccd811a.js:106080)
at NbOverlay.push../node_modules/@nebular/theme/components/cdk/overlay/mapping.js.NbOverlay.create (main.a72571efe1e9cccd811a.js:106055)
at NbOverlayService.push../node_modules/@nebular/theme/components/cdk/overlay/overlay.js.NbOverlayService.create (main.a72571efe1e9cccd811a.js:106832)
at NbContextMenuDirective.push../node_modules/@nebular/theme/components/context-menu/context-menu.directive.js.NbContextMenuDirective.createOverlay (main.a72571efe1e9cccd811a.js:108818)
at NbContextMenuDirective.push../node_modules/@nebular/theme/components/context-menu/context-menu.directive.js.NbContextMenuDirective.show (main.a72571efe1e9cccd811a.js:108798)
at SafeSubscriber._next (main.a72571efe1e9cccd811a.js:108855)
at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub (main.a72571efe1e9cccd811a.js:137557)
at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next (main.a72571efe1e9cccd811a.js:137495)

Expected behavior:
The user context menu will show upon click after router navigation.

Steps to reproduce:
The callback code that's triggering the issue is in the akveo/nebular repo.
https://github.com/akveo/nebular/blob/7e68c20a92dbe8f86ff728f0df6d4e771a0b7408/src/playground/with-layout/oauth2/oauth2-callback.component.ts

I even tried a variation of the existing logic by running it within OnInit and OnDestroy with the appropriate subscription disposable. It yields the same results.
The only thing that makes the user context menu to start rendering again is a hard-refresh of the browser.

Related code:

Other information:

npm, node, OS, Browser

Node, npm: `node --version` (v11.4.0) and `npm --version` (6.4.1)
OS: macOS Mojave
Browser: Chrome

Angular, Nebular

    "@nebular/auth": "3.1.0",
    "@nebular/bootstrap": "3.1.0",
    "@nebular/security": "3.1.0",
    "@nebular/theme": "3.1.0",
@stefanpartheym
Copy link

stefanpartheym commented Jan 11, 2019

Yep, having the same issue with NbPasswordAuthStrategy.

[EDIT]

The issue only occurs, if the redirect property is set (for either success or failure depending on the case, for me its redirect.success):

// ...
login: {
    endpoint: 'auth',
    method: 'post',
    redirect: {
        success: 'main', // I'm redirecting from route /auth to /main once login was successful
        failure: null
    }
},
// ...

I investigated on that issue in the file .../node_modules/@nebular/auth/components/login/login.component.js.
In the method NbLoginComponent.login() the router object is used to redirect to the configured route, which triggers the described issue.

// ...
NbLoginComponent.prototype.login = function () {
    var _this = this;
    this.errors = [];
    this.messages = [];
    this.submitted = true;
    this.service.authenticate(this.strategy, this.user).subscribe(function (result) {
        _this.submitted = false;
        if (result.isSuccess()) {
            _this.messages = result.getMessages();
        }
        else {
            _this.errors = result.getErrors();
        }
        var redirect = result.getRedirect();
        if (redirect) {
            setTimeout(function () {
                return _this.router.navigateByUrl(redirect); // <-- This line triggers the issue
            }, _this.redirectDelay);
        }
        _this.cd.detectChanges();
    });
};
// ...

pmstss added a commit to pmstss/ngrx-quiz that referenced this issue Jan 16, 2019
- proper routing for auth submodule
- local NbAuthComponent to avoid oddities of multi NbLayout instances (error like in akveo/nebular#1136)

-
@nnixaa nnixaa added this to the 3.3.0 milestone Jan 16, 2019
@issue-sh issue-sh bot added Sprint and removed Backlog labels Jan 24, 2019
@Tibing Tibing closed this as completed Feb 26, 2019
@Tibing Tibing reopened this Feb 26, 2019
@nnixaa
Copy link
Collaborator

nnixaa commented Feb 28, 2019

Cannot reproduce it. Could you someone consolidate a reproducible example at https://stackblitz.com/github/akveo/nebular-seed?

@Mubramaj
Copy link

Mubramaj commented Mar 7, 2019

I can confirm this issue on Nebular 3.4.0

@nnixaa nnixaa modified the milestones: 3.4.1, 3.5.0 Mar 14, 2019
@yggg yggg assigned Tibing and unassigned nnixaa Mar 28, 2019
@nnixaa
Copy link
Collaborator

nnixaa commented Apr 11, 2019

@Mubramaj, could you shed a bit more light, please? What would be the steps? Are there any changes to layout/routes/etc?

Would really appreciate any help on this.

@Gilmar-Gomes
Copy link

I beleave that is something related to NbOverlayContainerAdapter._containerElement member (is showing null in vscode debugger). So, when it calls getContainerElement().appendChild throws the error!

@LucasLopesr
Copy link

Someone got some palliative solution?

@nnixaa nnixaa modified the milestones: 3.6.0, 4.1.0, 4.2.0 Jun 14, 2019
@Ungolim
Copy link

Ungolim commented Jul 1, 2019

This issue effectively impedes the usage of the otherwise excellent ContextMenu and Dialog components and it should not be postponed any further

@yggg yggg added the quality label Jul 18, 2019
@longgt
Copy link

longgt commented Aug 5, 2019

I have same issue when combined nbContextMenu directive with nb-route-tabset.
In https://angular-7-master-6mmzen.stackblitz.io/ (Edit URL: https://stackblitz.com/edit/angular-7-master-6mmzen)

[Reproduce steps]

  1. App starts with AboutPage (Click Settings at the top-left corner will show context menu)
  2. Switch to ContactPage
    At this time, nbContextMenu in shared component will not work anymore.

@rushi721
Copy link

rushi721 commented Aug 8, 2019

I have the same problem.
Error is as follows :-
ERROR TypeError: Cannot read property 'appendChild' of null at NbOverlayContainerAdapter._createContainer (index.js:997) at NbOverlayContainerAdapter.getContainerElement (overlay.js:766) at NbOverlay._createHostElement (overlay.js:3177) at NbOverlay.create (overlay.js:3136) at NbOverlayService.create (index.js:1464) at NbSelectComponent.createOverlay (index.js:18650) at NbSelectComponent.attachToOverlay (index.js:18632) at NbSelectComponent.show (index.js:18537) at SafeSubscriber._next (index.js:18673) at SafeSubscriber.__tryOrUnsub (Subscriber.js:183)

@NileshDabi
Copy link

I also have the same problem with nebular toastr. Its not working in my lazy loaded feature module.

@niklasravnsborg
Copy link

I still got the issue in version 4.5.0

ERROR TypeError: Cannot read property 'appendChild' of null
    at NbOverlayContainerAdapter._createContainer (index.js:1043)
    at NbOverlayContainerAdapter.getContainerElement (overlay.js:768)
    at NbOverlay._createHostElement (overlay.js:3203)
    at NbOverlay.create (overlay.js:3162)
    at NbOverlayService.create (index.js:1647)
    at NbDynamicOverlay.createOverlay (index.js:11878)
    at NbDynamicOverlay.show (index.js:11841)
    at SafeSubscriber._next (index.js:12077)
    at SafeSubscriber.__tryOrUnsub (Subscriber.js:183)
    at SafeSubscriber.next (Subscriber.js:122)

@JrmyDev
Copy link

JrmyDev commented Nov 5, 2019

3.6.2 seems to fix this issue

@Ungolim
Copy link

Ungolim commented Nov 5, 2019

3.6.2 seems to fix this issue

no it does not, at least when there are lazy-loaded modules in the way

I still got the issue in version 4.5.0

ERROR TypeError: Cannot read property 'appendChild' of null
    at NbOverlayContainerAdapter._createContainer (index.js:1043)
    at NbOverlayContainerAdapter.getContainerElement (overlay.js:768)
    at NbOverlay._createHostElement (overlay.js:3203)
    at NbOverlay.create (overlay.js:3162)
    at NbOverlayService.create (index.js:1647)
    at NbDynamicOverlay.createOverlay (index.js:11878)
    at NbDynamicOverlay.show (index.js:11841)
    at SafeSubscriber._next (index.js:12077)
    at SafeSubscriber.__tryOrUnsub (Subscriber.js:183)
    at SafeSubscriber.next (Subscriber.js:122)

same here.. so frustrating, can't get around it with Context Menus, had to swap a different navigation menu system for production release

@niklasravnsborg
Copy link

niklasravnsborg commented Nov 5, 2019

@lepidotteri I used Nebular Auth and had to write a custom AuthComponent that doesn't use <nb-layout> itself, by default it does:

<nb-layout>
<nb-layout-column>
<nb-card>
<nb-card-header>
<nav class="navigation">
<a href="#" (click)="back()" class="link back-link" aria-label="Back">
<nb-icon icon="arrow-back"></nb-icon>
</a>
</nav>
</nb-card-header>
<nb-card-body>
<nb-auth-block>
<router-outlet></router-outlet>
</nb-auth-block>
</nb-card-body>
</nb-card>
</nb-layout-column>
</nb-layout>

From my understanding the menu only works correctly if the <nb-layout> stays consistent throughout navigation.

@Ungolim
Copy link

Ungolim commented Nov 5, 2019

@lepidotteri I used Nebular Auth and had to write a custom AuthComponent that doesn't use <nb-layout> itself, by default it does:

<nb-layout>
<nb-layout-column>
<nb-card>
<nb-card-header>
<nav class="navigation">
<a href="#" (click)="back()" class="link back-link" aria-label="Back">
<nb-icon icon="arrow-back"></nb-icon>
</a>
</nav>
</nb-card-header>
<nb-card-body>
<nb-auth-block>
<router-outlet></router-outlet>
</nb-auth-block>
</nb-card-body>
</nb-card>
</nb-layout-column>
</nb-layout>

From my understanding the menu only works correctly if the <nb-layout> stays consistent throughout navigation.

Thank you @niklasravnsborg, I had suspected as much; I didn't go that far but I did change the auth-module routes to test the behavior and it was working fine then.

I think they should either:

  1. change the component to be more standalone and resilient
  2. make NbMenuComponent more suitable (doesn't even have orientation atm?) and customizable for top-bar navigation purposes

@leohubert
Copy link

I have the same problem with 4.6.0 version of nebular.

<nb-action *ngIf="isLoggedIn">
    <nb-user [name]="user?.name" [picture]="'https://www.gravatar.com/avatar/' + user?.email_hash"
      [nbContextMenu]="accountMenuActions" nbContextMenuTag="account-menu" nbContextMenuTrigger="hover">
    </nb-user>
</nb-action>

If i logout and login again i have the same error.

ERROR TypeError: Cannot read property 'appendChild' of null
    at NbOverlayContainerAdapter._createContainer (index.js:1043)
    at NbOverlayContainerAdapter.getContainerElement (overlay.js:768)
    at NbOverlay._createHostElement (overlay.js:3203)
    at NbOverlay.create (overlay.js:3162)
    at NbOverlayService.create (index.js:1637)
    at NbDynamicOverlay.createOverlay (index.js:11473)
    at NbDynamicOverlay.show (index.js:11436)
    at SafeSubscriber._next (index.js:11672)
    at SafeSubscriber.__tryOrUnsub (Subscriber.js:183)
    at SafeSubscriber.next (Subscriber.js:122)

It can aslo appear after navigation on specific routes, always the same routes.

@mc-lovin
Copy link

What @niklasravnsborg suggested worked for me. The nb-layout tag needs to be consistent in the outer layout. i.e. it should always be the same outer nb-layout tag which is containing other layouts

@dcruz1990
Copy link

Whats the fix for this? im having same issue.

@leohubert
Copy link

leohubert commented Apr 21, 2020

I don't remember exactly but do you use multiple <nb-layout> in your projects ?
Personally i used many <nb-layout> in multiple vues, when i found a alternative to this it fixed so i think is linked :)

@omarahm3
Copy link

I have the same problem with 4.6.0 version of nebular.

<nb-action *ngIf="isLoggedIn">
    <nb-user [name]="user?.name" [picture]="'https://www.gravatar.com/avatar/' + user?.email_hash"
      [nbContextMenu]="accountMenuActions" nbContextMenuTag="account-menu" nbContextMenuTrigger="hover">
    </nb-user>
</nb-action>

If i logout and login again i have the same error.

ERROR TypeError: Cannot read property 'appendChild' of null
    at NbOverlayContainerAdapter._createContainer (index.js:1043)
    at NbOverlayContainerAdapter.getContainerElement (overlay.js:768)
    at NbOverlay._createHostElement (overlay.js:3203)
    at NbOverlay.create (overlay.js:3162)
    at NbOverlayService.create (index.js:1637)
    at NbDynamicOverlay.createOverlay (index.js:11473)
    at NbDynamicOverlay.show (index.js:11436)
    at SafeSubscriber._next (index.js:11672)
    at SafeSubscriber.__tryOrUnsub (Subscriber.js:183)
    at SafeSubscriber.next (Subscriber.js:122)

It can aslo appear after navigation on specific routes, always the same routes.

I'm also experiencing the exact same behavior, hope there are any updates to this bug

@tekmi
Copy link

tekmi commented Jul 17, 2020

I have experienced the same error: ERROR TypeError: Cannot read property 'appendChild' of null while I was playing with the nb-user component:

<nb-action class="user-action" *ngIf="isAuth">
      <nb-user
        [nbContextMenu]="userMenu"
        nbContextMenuTag="user-context-menu"
        [name]="user?.email"
        [onlyPicture]="userPictureOnly"
        [picture]="user?.picture">
      </nb-user>
</nb-action>

I could not load the userMenu context menu, only the hard refresh was bringing the things to normal...but this was not the ideal solution.

My main app component used the <app-header> component which had the offending <nb-user> component, as shown below :

<nb-layout>
  <nb-layout-header fixed>
    <app-header></app-header>
  </nb-layout-header>

  <nb-layout-column>
    <router-outlet></router-outlet>
  </nb-layout-column>

  <nb-layout-footer fixed>
    Footer
  </nb-layout-footer>
</nb-layout>

During route changes, my <router-outlet></router-outlet> was being replaced by the auth component which is presented below:

<nb-layout>
  <nb-layout-column>
    <nb-card>
      <nb-card-header>
        <nav class="navigation">Authentication</nav>
      </nb-card-header>
      <nb-card-body>
        <app-auth-block>
          <router-outlet></router-outlet>
        </app-auth-block>
      </nb-card-body>
    </nb-card>
  </nb-layout-column>
</nb-layout>

The surprising fix was to remove the <nb-layout> and <nb-layout-column> parts from my auth component...thus here it is how it looks now:

<nb-card>
  <nb-card-header>
    <nav class="navigation">Authentication</nav>
  </nb-card-header>
  <nb-card-body>
    <app-auth-block>
      <router-outlet></router-outlet>
    </app-auth-block>
  </nb-card-body>
</nb-card>

Thanks to this trick the error is gone and I can see the context menu while clicking on the user icon.

I hope this confirms that the error still exists, even in @nebular/theme: "^5.1.0" version. Plus, the suggestions from previous people here, that having only one <nb-layout> surprisingly fixes this weird error. Thank you guys!

@vonbeitthia
Copy link

solved adding one space in path definition:
const rutas: Routes = [
{ path: 'clientes',
loadChildren: () => import('./clientes/clientes.module').then(m => m.ClientesModule)
},
{
path: ' ', // para no generar errores debe estar en blanco
component: AppComponent,
pathMatch: 'full'
}
];

@truonghoangduy
Copy link

I resolve the issue here #1663 link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.