angular-slider / ngx-slider

Self-contained, mobile friendly slider component for Angular based on angularjs-slider
https://angular-slider.github.io/ngx-slider/
MIT License
387 stars 175 forks source link

Compatibility with Angular Universal #66

Open BenjaminDish opened 5 years ago

BenjaminDish commented 5 years ago

Hello,

I'm trying to integrate the component into my app, using Universal server-side rendering.

My code works fine (thanks for this good component!) without the SSR.

When running with SSR, this error occurs :

ERROR TypeError: this.elemRef.nativeElement.getBoundingClientRect is not a function
    at MinHDirective.JqLiteWrapper.getBoundingClientRect (path_to_project\node_modules\ng5-slider\bundles\ng5-slider.umd.js:201:43)

So it seems that the component doesn't deal with SSR constraints (no access to browser window, etc..).

Should it be possible to make this component working with Universal ? In the meantime, did someone find a workaround ?

piotrdz commented 5 years ago

No, I'm afraid the slider component is currently very closely tied to the browser. getBoundingClientRect() is necessary to calculate slider bounds and position the sub-elements accordingly.

To support something like Angular Universal, the slider layout would need to be re-written to use pure CSS in some clever way. I would have to research this further to see if this is possible. It would be actually a good thing to do, because it would also solve current performance issues.

harellevy commented 5 years ago

see https://github.com/angular-slider/ng5-slider/pull/74 , to avoid wrap ng5-slider element with *ngIf, if it wouldn't render in the ssr it won't run the error in server side.

harellevy commented 5 years ago

just put in the constructor like this:

isBrowser: boolean;
constructor(@Inject(PLATFORM_ID) private platformId) {
    this.isBrowser = isPlatformBrowser(platformId);
}

and

*ngIf="isBrowser"

in the element that wraps ng5-slider component

piotrdz commented 5 years ago

I have replied to the PR in #74 - this is a quick workaround, which does not solve the underlying problem. I have declined the PR as a result.

I have documented no support for Angular Universal as a known issue for now. I will keep this ticket open until a long-term solution is found.

Webjin commented 5 years ago

+1 for a more elegant solution to this problem

alexxsanya commented 5 years ago

just put in the constructor like this:

isBrowser: boolean;
constructor(@Inject(PLATFORM_ID) private platformId) {
    this.isBrowser = isPlatformBrowser(platformId);
}

and

*ngIf="isBrowser"

in the element that wraps ng5-slider component

@harellevy thank you very much for this. It has resolved the TypeError: this.elemRef.nativeElement.getBoundingClientRect is not a function and ReferenceError: window is not defined I had when using ng5-slider.

hesampour commented 4 years ago

same problem for showing modal in angular universal.
@harellevy method cause another error for showing modal.

sutin1234 commented 4 years ago

const domino = require('domino');
const window = domino.createWindow(indexHtml); global['window'] = window; global['document'] = window.document;

66 Angular SSR only

TGihan commented 3 years ago

just put in the constructor like this:

isBrowser: boolean;
constructor(@Inject(PLATFORM_ID) private platformId) {
    this.isBrowser = isPlatformBrowser(platformId);
}

and

*ngIf="isBrowser"

in the element that wraps ng5-slider component

@harellevy Thank you very much. I had same issue while using angular-responsive-carousel with SSR. It resolved my issue.

eminvegan commented 3 years ago

just put in the constructor like this:

isBrowser: boolean;
constructor(@Inject(PLATFORM_ID) private platformId) {
    this.isBrowser = isPlatformBrowser(platformId);
}

and

*ngIf="isBrowser"

in the element that wraps ng5-slider component

Thank You Very Much!