0

I have created an Angular SSR app, there I have installed NgApexchartsModule module, after this when I try to run the below command I am facing this issue:

 command: ng run abc:serve-ssr

ReferenceError: window is not defined
    at Object.ujAs (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:230211:345871)
    at __webpack_require__ (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:20:30)
    at Module.CV0D (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:91098:68)
    at __webpack_require__ (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:20:30)
    at Module.ZAI4 (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:127394:72)
    at __webpack_require__ (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:20:30)
    at Module.24aS (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:55649:69)
    at __webpack_require__ (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:20:30)
    at Module.K011 (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:102532:80)
    at __webpack_require__ (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:20:30)

A server error has occurred.
node exited with 1 code.
connect ECONNREFUSED 127.0.0.1:59450

Configuration:

app.module.ts

    imports: [
    BrowserModule,
    BrowserAnimationsModule,
    MaterialModuleComponents,
    NgbModule,
    NgxGaugeModule,
    HttpClientModule,
    NgxMatIntlTelInputModule,
    Ng2SearchPipeModule,
    NgxSpinnerModule,
    **NgApexchartsModule**,
    NgpImagePickerModule,
    NgxFileDragDropModule,
    MatDatetimepickerModule,
    MatNativeDatetimeModule,
    NgxSkeletonLoaderModule.forRoot(),
    JoyrideModule.forRoot(),
    BrowserModule.withServerTransition({ appId: 'serverApp' })
  ],

Server.ts

import 'zone.js/dist/zone-node';
import { ngExpressEngine } from '@nguniversal/express-engine';
import * as express from 'express';
import { join } from 'path';
import { AppServerModule } from './src/main.server';
import { APP_BASE_HREF } from '@angular/common';
import { existsSync } from 'fs';

import {enableProdMode} from '@angular/core';

enableProdMode();


// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
  const server = express();
  const distFolder = join(process.cwd(), 'dist/abc/browser');
  const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';

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


  // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
  server.engine('html', ngExpressEngine({
    bootstrap: AppServerModule,
  }));

  server.set('view engine', 'html');
  server.set('views', distFolder);

  // Example Express Rest API endpoints
  // server.get('/api/**', (req, res) => { });
  // Serve static files from /browser
  server.get('*.*', express.static(distFolder, {
    maxAge: '1y'
  }));

  // All regular routes use the Universal engine
  server.get('*', (req, res) => {
    res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
  });

  return server;
}

function run(): void {
  const port = process.env.PORT || 4000;

  // Start up the Node server
  const server = app();
  server.listen(port, () => {
    console.log(`Node Express server listening on http://localhost:${port}`);
  });
}

// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
  run();
}

export * from './src/main.server';

app.server.module.ts

import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';

import { AppModule } from './app.module';
import { AppComponent } from './app.component';

@NgModule({
  imports: [
    AppModule,
    ServerModule,
  ],
  bootstrap: [AppComponent],
})
export class AppServerModule {}

I tried with window element also which I have motioned in the above code but still facing the same issue. Thanks in advance.

5
  • have you declared the window variable? Commented Jun 1, 2021 at 7:18
  • yes..@BharatChoudhary, updated the question please check Commented Jun 1, 2021 at 7:21
  • stackoverflow.com/questions/66553213/…, would this work for you? Commented Jun 1, 2021 at 7:25
  • No..@BharatChoudhary, I must import that module Commented Jun 1, 2021 at 7:32
  • do you have any alternative..? Commented Jun 1, 2021 at 7:32

1 Answer 1

1

Your problem is you're using SSR .. and in the server window doesn't EXIST ... so you can basically check for which environment you're in (client or server)

you can do it like this:

Check with a directive on the HTML where you put your apex chart if you're in browser or server

the directive:

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

@Directive({
    selector: '[SSR]'
})
export class SSRDirective implements OnInit {

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

    ngOnInit() {
        if (isPlatformServer(this.platformId)) {
            this.viewContainer.clear();
        } else {
            this.viewContainer.createEmbeddedView(this.templateRef);
        }

    }
}

And you can use like this:

<apextag   [bidings]
 *SSR> 
            </apextag>
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the answer @federico scamuzzi, but here the problem is I haven't implemented the charts fully, just I installed the apex chart library and then imported in " imports section in app.module.ts file" , that's it...if I try to compile then the above error is showing, is it possible to handle your solution in app.module.ts file ?
mmm no.. can you post the app.module and app.module.server files?
Updated the question please verify it @federico scamuzzi
I know it is too late but I was facing the same issue, I tried to create a separate module where I was using apexcharts and used that module (removed import from AppModule) from route and loaded as a child component. That worked for me as while bootstrapping the angular app apexcharts will not come into the consideration and it will fix the issue.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.