Components: Overlay SSR support

Created on 20 Dec 2017  路  11Comments  路  Source: angular/components

Bug, feature request, or proposal:

Feature request, maybe.

What is the expected behavior?

Overlays work in server-side rendering.

What is the current behavior?

It doesn't work in server-side rendering.

What are the steps to reproduce?

Create a simple app which opens a dialog, and it will fail on server.

What is the use-case or motivation for changing an existing behavior?

However positioning without DOM, might be hard or impossible, simple use cases which is used in the opening dialog can be easy to handle. Opening dialog on server is the most important motivation, as it's common to have opened dialogs in some routes.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Angular CLI: 1.5.4
Node: 6.9.1
OS: win32 x64
Angular: 5.1.1
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router

@angular/cdk: 5.0.1
@angular/cli: 1.5.4
@angular/flex-layout: 2.0.0-beta.10-4905443
@angular/material: 5.0.1
@angular-devkit/build-optimizer: 0.0.33
@angular-devkit/core: 0.0.21
@angular-devkit/schematics: 0.0.37
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.8.4
@schematics/angular: 0.1.7
typescript: 2.4.2
webpack: 3.8.1

P4 cdoverlay feature

All 11 comments

For the most part overlays should at least compile using Universal already. Have you run into any particular issues?

@crisbeto I got OverlayRef error and the error message is below.

ERROR TypeError: Cannot read property 'style' of null
    at GlobalPositionStrategy.apply (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:57961:85)
    at OverlayRef.updatePosition (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:56959:43)
    at SafeSubscriber._next (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:56792:19)
    at SafeSubscriber.__tryOrUnsub (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:24501:16)
    at SafeSubscriber.next (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:24448:22)
    at Subscriber._next (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:24388:26)
    at Subscriber.next (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:24352:18)
    at TakeSubscriber._next (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:41616:30)
    at TakeSubscriber.Subscriber.next (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:24352:18)
    at SafeSubscriber.schedulerFn [as _next] (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:4610:52)
    at SafeSubscriber.__tryOrUnsub (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:24501:16)
    at SafeSubscriber.next (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:24448:22)
    at Subscriber._next (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:24388:26)
    at Subscriber.next (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:24352:18)
    at EventEmitter.Subject.next (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:24588:25)
    at EventEmitter.emit (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:4590:46)
    at /Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:4995:79
    at ZoneDelegate.invoke (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:164330:26)
    at Zone.run (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:164080:43)
    at NgZone.runOutsideAngular (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:4972:69)
    at checkStable (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:4995:26)
    at Object.onHasTask (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:5037:21)
    at ZoneDelegate.hasTask (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:164383:37)
    at ZoneDelegate._updateTaskCount (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:164403:22)
    at Zone._updateTaskCount (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:164227:34)
    at Zone.runTask (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:164147:30)
    at ZoneTask.invokeTask (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:164437:34)
    at ZoneTask.invoke (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:164426:48)
    at data.args.(anonymous function) (/Users/sangmin/WebstormProjects/mms-mobile-angular/dist/server.js:165119:25)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)

https://github.com/angular/material2/blob/a626c8f5f4b97c7e73fe689340a6e9e5e20489dd/src/cdk/overlay/overlay-ref.ts#L205
here is the cause line

Thanks @leo6104, that one should be resolved by https://github.com/angular/material2/pull/8422 in the next release.

Hi,

I'm encountering this error on the MatDialog for SSR rendering:

ERROR ReferenceError: document is not defined at BlockScrollStrategy._canBeEnabled (C:\Users\user1\Documents\angular-projects\gma-psst\dist-server\server.js:56186:13) at BlockScrollStrategy.enable (C:\Users\user1\Documents\angular-projects\gma-psst\dist-server\server.js:56135:18) at OverlayRef.attach (C:\Users\user1\Documents\angular-projects\gma-psst\dist-server\server.js:56452:41) at MatDialog._attachDialogContainer (C:\Users\user1\Documents\angular-projects\gma-psst\dist-server\server.js:134809:53) at MatDialog.open (C:\Users\user1\Documents\angular-projects\gma-psst\dist-server\server.js:134705:53) at Timeout.<anonymous> (C:\Users\user1\Documents\angular-projects\gma-psst\dist-server\server.js:244397:36095) at ZoneDelegate.invokeTask (C:\Users\user1\Documents\angular-projects\gma-psst\dist-server\server.js:166249:31) at Object.onInvokeTask (C:\Users\user1\Documents\angular-projects\gma-psst\dist-server\server.js:5012:33) at ZoneDelegate.invokeTask (C:\Users\user1\Documents\angular-projects\gma-psst\dist-server\server.js:166248:36) at Zone.runTask (C:\Users\user1\Documents\angular-projects\gma-psst\dist-server\server.js:166016:47) at ZoneTask.invokeTask (C:\Users\user1\Documents\angular-projects\gma-psst\dist-server\server.js:166324:34) at Timeout.ZoneTask.invoke (C:\Users\user1\Documents\angular-projects\gma-psst\dist-server\server.js:166313:48) at Timeout.timer [as _onTimeout] (C:\Users\user1\Documents\angular-projects\gma-psst\dist-server\server.js:167839:29) at ontimeout (timers.js:380:14) at tryOnTimeout (timers.js:244:5) at Timer.listOnTimeout (timers.js:214:5

What do you think's wrong?

Thanks @wtubog, I've submitted https://github.com/angular/material2/pull/9665 with a fix.

There's more error @crisbeto:

ERROR TypeError: Cannot read property 'autoFocus' of undefined at MatDialogContainer._trapFocus (/web/gmanetwork/gno-psst/dist-server/server.js:134226:25) at MatDialogContainer._onAnimationDone (/web/gmanetwork/gno-psst/dist-server/server.js:134279:18) at Object.handleEvent (/web/gmanetwork/gno-psst/dist-server/server.js:244397:338925) at Object.handleEvent (/web/gmanetwork/gno-psst/dist-server/server.js:13828:155) at Object.handleEvent (/web/gmanetwork/gno-psst/dist-server/server.js:14560:29) at dispatchEvent (/web/gmanetwork/gno-psst/dist-server/server.js:10243:25) at /web/gmanetwork/gno-psst/dist-server/server.js:10868:38 at /web/gmanetwork/gno-psst/dist-server/server.js:145777:25 at Array.forEach (native) at /web/gmanetwork/gno-psst/dist-server/server.js:145775:53 at ZoneDelegate.invoke (/web/gmanetwork/gno-psst/dist-server/server.js:166216:26) at Object.onInvoke (/web/gmanetwork/gno-psst/dist-server/server.js:5021:33) at ZoneDelegate.invoke (/web/gmanetwork/gno-psst/dist-server/server.js:166215:32) at Zone.run (/web/gmanetwork/gno-psst/dist-server/server.js:165966:43) at NgZone.run (/web/gmanetwork/gno-psst/dist-server/server.js:4838:69) at /web/gmanetwork/gno-psst/dist-server/server.js:145774:29 at ZoneDelegate.invoke (/web/gmanetwork/gno-psst/dist-server/server.js:166216:26) at Zone.run (/web/gmanetwork/gno-psst/dist-server/server.js:165966:43) at /web/gmanetwork/gno-psst/dist-server/server.js:166686:57 at ZoneDelegate.invokeTask (/web/gmanetwork/gno-psst/dist-server/server.js:166249:31) at Zone.runTask (/web/gmanetwork/gno-psst/dist-server/server.js:166016:47) at drainMicroTaskQueue (/web/gmanetwork/gno-psst/dist-server/server.js:166423:35)

Can you suggest a temporary work around for this? Thank you!

That's really weird. I did manage to reproduce a couple of errors when trying to open a dialog on the server, but neither was the same as yours (one was the error with BlockScrollStrategy that you reported earlier and the other one points here). I'll submit a fix for the error that I'm seeing and while not ideal, you should be able to work around the issue by not opening a dialog if you're on the server. Here's what that could look like:

import {Platform} from '@angular/cdk/platform';

class YourComponent {
  constructor(platform: Platform, dialog: MatDialog) {
    if (platform.isBrowser) {
       dialog.open(...);
    }
  }
}

I also get another one, it does render SSR but it spits out a nasty error in the console on the server.

ERROR ReferenceError: window is not defined
    at ViewportRuler._updateViewportSize (/Applications/Web/kaufmann-nextgen/source/dist/server.js:65716:39)
    at ViewportRuler.getViewportSize (/Applications/Web/kaufmann-nextgen/source/dist/server.js:65632:18)
    at BlockScrollStrategy._canBeEnabled (/Applications/Web/kaufmann-nextgen/source/dist/server.js:62525:61)
    at BlockScrollStrategy.enable (/Applications/Web/kaufmann-nextgen/source/dist/server.js:62469:18)
    at OverlayRef.attach (/Applications/Web/kaufmann-nextgen/source/dist/server.js:62802:41)
    at OverlayService.attachDialogContainer (/Applications/Web/kaufmann-nextgen/source/dist/server.js:187996:56)
    at OverlayService.open (/Applications/Web/kaufmann-nextgen/source/dist/server.js:187905:54)
    at Timeout.<anonymous> (/Applications/Web/kaufmann-nextgen/source/dist/server.js:157491:46)
    at ZoneDelegate.invokeTask (/Applications/Web/kaufmann-nextgen/source/dist/server.js:132236:31)
    at Object.onInvokeTask (/Applications/Web/kaufmann-nextgen/source/dist/server.js:5957:33)

I just tested with latest version (6.4.1), and dialogs are rendering properly in SSR, but there is another issue which is more critical than the previous one! Client-side dialog is opened on top of Server-side rendered dialog which remains open and blocks UI and there is no way to get rid of it!

this should be fixed in #11940
but it has not been merged yet

I'm getting a very strange error when rendering dialogs in the server-side;

This is my SSR dialog result, which is fine:

image

That's what happens to it when Angular starts running (bootstraps) in the client side:

image

So, I have no idea on why would my dialog "crash" like that in the client even after being well redered by the server. 馃槩

Was this page helpful?
0 / 5 - 0 ratings