ng build --prod dynamic variables get lost

197 Views Asked by At

i have a ngModule which uses ngx-socket-io, i removed the unnecessary imports and injections :) as you can see i have commented some code which works like charm only in development build of application, as soon as i build the app using --prod those variables wont work anymore, if logged to the console the value is the same as static declaration yet SocketIoModule.forRoot(socketConfig) wont see them if build using --prod flag

import { SocketIoModule, SocketIoConfig } from "ngx-socket-io";
const socketConfig = {
    url: 'http://localhost:3000',
    options: {
        query: {
            userId: "f9ae03de-f043-4704-882e-d269ee514805"
        }
    }
};

// const userId = (<any>window).MaxDuel.instance.userId;
// const socket = (<any>window).MaxDuel.instance.socket;
// const socketConfig = {url: socket, options: {query: {userId}}};
// const socketConfig2 = JSON.parse(JSON.stringify(socketConfig));
console.log(socketConfig);

@NgModule({
  declarations: [],
  imports: [
    SocketIoModule.forRoot(socketConfig)
  ],
  entryComponents: [],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

but after commenting the variables and introducing the same copy but in static declaration, application starts working again! as you can see i even serialized and deserialized to simulate a static declaration but again nothing!

the main problem is i need the userId on connection and that variable can not be static

1

There are 1 best solutions below

0
On

It is because when you run ng build --prod AOT compiler is used by default which means your code gets build on the server and being served to the user. At that point, there is no window object or MaxDuel object. So, you need to find another way. Lucky for you, there is!

I read the documentation of the library you use. There is another way to instantiate Socket. Here you can read about it

You need to create your own Socket and provide it.

import { Injectable, NgModule } from '@angular/core';
import { Socket } from 'ngx-socket-io';

@Injectable()
export class MySocket extends Socket {

    constructor() {
        super({url: window.MaxDuel.instance.socket, 
               options: {
                 query: {window.MaxDuel.instance.userId
              }});
    }

}

@NgModule({
  declarations: [
    //components
  ],
  imports: [
    SocketIoModule,
    //...
  ],
  providers: [{
     provide: Socket, useClass: MySocket
  }],
  bootstrap: [/** AppComponent **/]
})
export class AppModule { }

Now, you can inject Socket anywhere in your application and use it just fine.