plotly / angular-plotly.js

MIT License
233 stars 77 forks source link

Incompatible with ngniversal? #106

Closed thenetimp closed 4 years ago

thenetimp commented 4 years ago

We have an angular8 app. Yesterday I upgraded it to angular9 and installed ng universal. I performed ssr:build and it builds clean, however when I run ssr:serve

ReferenceError: document is not defined var style = document.getElementById(id);

This bug seems to come from trying to build plotly into the angular app, so I switched to the CDN version and get a very similar error:w

ReferenceError: document is not defined at Timeout.init (/usr/src/ob-console-app/dist/server/main.js:100610:46)

but in a function related to angular-plotlyjs

                    PlotlyViaCDNModule.loadViaCDN = function() {
                        PlotlyService.setPlotly('waiting');
                        var init = function() {
                            var src = PlotlyViaCDNModule_1._plotlyBundle == null ?
                                "https://cdn.plot.ly/plotly-" + PlotlyViaCDNModule_1._plotlyVersion + ".min.js" :
                                "https://cdn.plot.ly/plotly-" + PlotlyViaCDNModule_1._plotlyBundle + "-" + PlotlyViaCDNModule_1._plotlyVersion + ".min.js";
                            var script = document.createElement('script');

The last line "document.createElement('script');" is where it failed

I went back to v8 and tried it there, and it is the same issue with V8 so this is not related to v9 but I think to angular universal.

andrefarzat commented 4 years ago

Hello, @thenetimp. Never tried the ng universal tool, but I am not sure that the PlotlyViaCDNModule would work on the server side since it uses the document. Please check the link : https://angular.io/guide/universal#working-around-the-browser-apis

I believe you could use the PlotlyViaWindowModule (please check: https://github.com/plotly/angular-plotly.js#plotly-via-window-module) and add the plotly.js as a global script on angular.json.

Please, let me know if this solves your issue 😸

thenetimp commented 4 years ago

I've already walked away from using the plugin and have written my own code to use PlotlyJS.

nbittich commented 3 years ago

@andrefarzat this solution worked for me:


import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { PlotlyService, ɵa } from "angular-plotly.js";
import { Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from "@angular/common";
import { WindowRefService } from '@core/service/window.service';

@NgModule({
  declarations: [],
  imports: [CommonModule, ɵa],
  providers: [PlotlyService],
  exports: [ɵa],
})
export class PlotlyUniversalModule {
  constructor(@Inject(PLATFORM_ID) private platformId: any, private windowService: WindowRefService) {
    if (isPlatformBrowser(platformId)) {
      const plotly = (windowService.nativeWindow as any).Plotly;
      if (typeof plotly === 'undefined') {
        throw new Error(`Plotly object not found on window.`);
      }
      PlotlyService.setPlotly(plotly);

    }
  }

}