Nebular: NbOverlayContainerAdapter and Lazy Loading

Created on 25 Oct 2018  路  13Comments  路  Source: akveo/nebular

Issue type

I'm submitting a bug report

Issue description

Current behavior:
When a lazy loaded module is opened, a NbOverlayContainerAdapter gets constructed along with it which wont have its setContainer() called. This causes the nbDialog to fail in _createContainer()

Expected behavior:
setContainer() should be called, or createContainer() should append to document body if container undefined

Steps to reproduce:

  • Create a lazyloaded module and route to its component.
  • Try to open a nbDialog with NbDialogService injected
  • Check console

Related code:
Please try to open the dialog from the lazy loaded module, sm and check stackblitz console.

https://stackblitz.com/edit/nebular-overlay-container-adapter-bug

Other information:

Console logs:
ERROR TypeError: Cannot read property 'appendChild' of undefined at NbOverlayContainerAdapter._createContainer (theme.umd.js:1907) at NbOverlayContainerAdapter.OverlayContainer.getContainerElement (overlay-container.ts:40) at NbOverlay.createHostElement (theme.umd.js:1289) at NbOverlay.create (theme.umd.js:1246) at NbOverlayService.create (theme.umd.js:1859) at NbDialogService.createOverlay (theme.umd.js:12724) at NbDialogService.open (theme.umd.js:12714) at LcmpComponent.openDialog (VM4956 lcmp.component.ts:21) at Object.eval [as handleEvent] (LcmpComponent.html:1) at handleEvent (view.ts:138)

npm, node, OS, Browser

Node: v8.10  npm: v6.4.1
OS: Windows 10
Browser: All

Angular, Nebular

    "@angular/cdk": "^6.4.7",
    "@angular/common": "6.1.9",
    "@angular/compiler": "6.1.9",
    "@angular/core": "6.1.9",
    "@angular/forms": "6.1.9",
    "@angular/http": "6.1.9",
    "@angular/platform-browser": "6.1.9",
    "@angular/platform-browser-dynamic": "6.1.9",
    "@angular/router": "6.1.9",
    "@nebular/auth": "^2.0.0",
    "@nebular/theme": "^2.0.0",
    "@nebular/security": "^2.0.0",

What I have observed is that, only when NbLayout is constructed you call the setContainer()
Also I dont get consistent behavior when i wrap lazy-component with NbLayout

Please look into this issue :)

urgent bug

Most helpful comment

Same issue happening when add nb-select inside Feature module. Not working even with nb-layout wrapping all app. Any help?

All 13 comments

Same issue here.

Hi Guys! As it mentioned in the documentation, you have to wrap all the entire application in the nb-layout. I saw you've tried that, and you're failed but you were very close 馃槃
To achieve the desired behavior you have to wrap all your app in the nb-layout it means you have to just wrap the app.component's router-outlet in it. I did it in your stackblitz and all works fine.

Hello @Tibing , I am using ngx-admin and I have app.component as just while the pages component inherits the layouts and gets me the overall page view. Add your solution to the appendChild issue makes it more compact and gets me a boxed layout. Can you please help me on this ?
To be precise, i have two layout components in my augury.
One : Because i have wrapped of app.component.html within
Two : Because i have my main content wrapped inside a already. (With all the header menu and sidebar menu, which cannot be compromised)

Hi @Vbboi24, could you please create new issue for your question, also as provide reproducible stackblitz?

Yes Sure, I have already created a issue with ngx-admin repo
https://github.com/akveo/ngx-admin/issues/1933#issue-385021735
Should i be creating a duplicate ? If i should, yeah. I'm asking only because i dont want to create duplicate issues to this beautiful Repo <3

Same issue happening when add nb-select inside Feature module. Not working even with nb-layout wrapping all app. Any help?

@Tibing Wrapping the app component's router outlet in nb-layout breaks ngx-admin. The pages component's router outlet is already wrapped in nb-layout, so wrapping the app component messes up the layout.

Is there an alternative for ngx-admin?

So I tried:

  1. Removing ngx-sample-layout from pages.component.ts's template
  2. Wrapping router-outlet in app.component.ts's template

But I still get:

ERROR TypeError: "this.container is undefined"

(That's the Firefox equivalent of the Chrome error in the original post.)

Modified app.component.ts:

@Component({
selector: 'ngx-app',
template: `
<nb-layout>
    <nb-layout-column>
        <router-outlet></router-outlet>
    </nb-layout-column>
</nb-layout>`,
})

Workaround: Eager load the module. (I guess that's obvious given the title, but I tinkered for a long time before getting there!)

Now NbDialogService works, but there's another issue: The dialog pushes all content to the top of the screen on pages with a scrollbar when you've scrolled down. But that's another can of worms....I'm guessing it's specific to ngx-admin's layout.

@Mayocampo hello bro, did you find a solution for this bug?

I had the same issue with a nested child route, had a working <nb-select> on the main <nb-layout> and i wanted to have another <nb-select> on a sub child route, app router > child > child.

I SOLVED it by wrapping the third <router-outlet> like this

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

Sub child Module

@NgModule({
  imports: [
    ......
    NbSelectModule
  ]
})

@Nebular 4.x.x
@Angular 8.x.x

Solved this problem by removing the providers in @NgModule

@NgModule({
    imports: [...MODULES, ...NB_MODULES, ...FR_MODULES],
    exports: [...MODULES, ...NB_MODULES, ...PIPES, ...COMPONENTS, ...ENTRY_COMPONENTS, ...DIRECTIVES],
    declarations: [...COMPONENTS, ...ENTRY_COMPONENTS, ...PIPES, ...DIRECTIVES],
    entryComponents: [...ENTRY_COMPONENTS],
    providers: [
        ...NbThemeModule.forRoot(
            {
                name: 'default',
            },
            [DEFAULT_THEME, COSMIC_THEME, CORPORATE_THEME, DARK_THEME],
        ).providers,
    ],
})

Hi Guys! As it mentioned in the documentation, you have to wrap all the entire application in the nb-layout. I saw you've tried that, and you're failed but you were very close 馃槃
To achieve the desired behavior you have to wrap all your app in the nb-layout it means you have to just wrap the app.component's router-outlet in it. I did it in your stackblitz and all works fine.

Worked with me Thanks a lot

Was this page helpful?
0 / 5 - 0 ratings