ng2-nouislider icon indicating copy to clipboard operation
ng2-nouislider copied to clipboard

SSR: ERROR ReferenceError: document is not defined

Open vsilva472 opened this issue 6 years ago • 3 comments

After compile without errors with SSR when get serve up an error appears on console and theres no component rendered inside view.

The error is the following: Node server listening on http://localhost:4000 Running on the server with appId=rje-frontend ERROR ReferenceError: document is not defined at testOptions (C:\rjefrontend\dist\server.js:152857:11) at Object.initialize [as create] (C:\rjefrontend\dist\server.js:154277:17) at NouisliderComponent.ngOnInit (C:\rjefrontend\dist\server.js:151805:34) at checkAndUpdateDirectiveInline (C:\rjefrontend\dist\server.js:12909:19) at checkAndUpdateNodeInline (C:\rjefrontend\dist\server.js:14173:20) at checkAndUpdateNode (C:\rjefrontend\dist\server.js:14135:16) at prodCheckAndUpdateNode (C:\rjefrontend\dist\server.js:14675:5) at Object.updateDirectives (C:\rjefrontend\dist\server.js:53509:4282) at Object.updateDirectives (C:\rjefrontend\dist\server.js:14464:72) at checkAndUpdateView (C:\rjefrontend\dist\server.js:14117:14)

SSR implemented by the angular oficial tutorial Is there one way to make this awesome plugin work with Angular Universal?

Plugin version from package.json { "ng2-nouislider": "^1.7.11" "nouislider": "^11.1.0 }

Details of my environment: Angular CLI: 6.0.8 Node: 8.11.1 OS: win32 x64 Angular: 6.0.7

EDIT: After look inside server.js at line 152857 i found a try to create a htmlElement: var d = document.createElement("div");

I think this is part of core of nouislider.js. Is there one way to edit this to use angular way instead direct access to dom or bypass this only from SSR?

vsilva472 avatar Jul 13 '18 13:07 vsilva472

Same issue here

alexnoise79 avatar Jul 14 '18 19:07 alexnoise79

Same issue, someone have an idea?

KxL51 avatar Jul 24 '18 14:07 KxL51

I found a suitable workaround that isn't perfect but will help to fix SSR issues.

Simply prevent the slider from appearing when rendered by the server and use in only isPlatformBrowser().

You can do this using a AppShellNoRender Directive. I took the following example from here: https://blog.angular-university.io/angular-universal/

This is my directive

import {Directive, Inject, OnInit, PLATFORM_ID, TemplateRef, ViewContainerRef} from '@angular/core';
import {isPlatformServer} from '@angular/common';

@Directive({
    selector: '[appShellNoRender]'
})
export class AppShellNoRenderDirective implements OnInit {

    constructor(
        private viewContainer: ViewContainerRef,
        private templateRef: TemplateRef<any>,
        @Inject(PLATFORM_ID) private platformId
    ) { }

    ngOnInit() {
        console.log('Is Server:', isPlatformServer(this.platformId));
        if (isPlatformServer(this.platformId)) {
            this.viewContainer.clear();
        } else {
            this.viewContainer.createEmbeddedView(this.templateRef);
        }

    }
}

And applied to my noUislider...

<nouislider #priceRange [config]="priceRangeConfig" formControlName="priceRange" class="price-range" fxFlex fxFlex.xs="none" *appShellNoRender></nouislider>

Now when rendered by the server the document not found error doesn't appear as noUIslider is removed.

However when using a browser it will appear.

I hope this helps :-)

adskiremote avatar Nov 03 '18 05:11 adskiremote