Dean Friedland
Dean Friedland

Reputation: 803

Angular 5: Function calls are not supported in decorators

I am building a PWA from my Angular app and I am getting the following error when I run ng build --prod:

ERROR in app\app.module.ts(108,64): Error during template compile of 'AppModule'
Function calls are not supported in decorators but 'Environment' was called in 'environment'
'environment' calls 'Environment'.

However, it makes no sense because I added export to the class as you can see here:

environment.prod.ts

import { BaseEnvironment } from './base-environment';
import { ProspectBuilderModel } from '../app/models/prospect';

export class Environment extends BaseEnvironment {
  production: boolean = true;
  prospectBuilderModel: ProspectBuilderModel = {
    buildQuote: false,
    buildAcknowledge: false,
    buildOrganizationInfo: false,
    buildFinancialInfo: false,
    buildTradeInfo: false,
    buildPermissiblePurpose: false,
    buildUserSetup: false,
    buildPackageSelection: false,
    buildPaymentOptions: false,
    buildOrderOptions: false,
    buildVerifyOrganizationInfo: false,
    buildDocusignAuthorization: false,
    buildDocusignContract: false
  };
}

export const environment = new Environment();

base-environment.ts

import { ProspectBuilderModel } from '../app/models/prospect';

export abstract class BaseEnvironment {
  abstract production: boolean;
  abstract prospectBuilderModel: ProspectBuilderModel;
}

app.module.ts

...
 ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    MultiselectDropdownModule,
    ReactiveFormsModule,
    HttpModule,
    ToastrModule.forRoot(),
    BrowserAnimationsModule,
    NgxMyDatePickerModule.forRoot(),
    PopoverModule.forRoot(),
    ModalModule.forRoot(),
    ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production })
  ],
  providers: [
...

Does anyone know what I can do to resolve this error?

Upvotes: 3

Views: 5644

Answers (3)

ya_dimon
ya_dimon

Reputation: 3812

Had same problem, here are possible workarounds (if you don't have dynamically loaded properties):

1. As your answer, just object.

But you lose default properties and information about "to implement" properties.

2. Use static classes:

here you lose 'to implement' properties, since abstract statics are not possible, but you have the types and defaults.

// default.env.ts
export class BaseEnvironment {
  public production: boolean = true;
  public specialPropToImpl: boolean = true;
}

// your.env.ts
export class Environment extends BaseEnvironment {
  public specialPropToImpl = true;
}

export const environment = Environment;

3. Use default properties object, interface and object assignment:

here you have the 'to implement' properties, types and defaults, but little bit ugly to implement.

// default.env.ts
export interface EnvProperties {
  production: boolean;
  specialPropToImpl: boolean;
}

export const defaultEnv = {
  production: true
};

// your.env.ts
export const environment: EnvProperties = {
  ...defaultEnv,
  specialPropToImpl: true
};

4. Just one static variable more from environment

simple solution, you keep your subclasses, but every env file must have it. But since new environment files are created by copypaste of old one, this can work.
Depends on production value, you should change the variable value manually.
Not very flexible and maintainable solution. But simple.

// your.env.ts
export const enablePwa = true

// app.module.ts
import {environment, enablePwa} from 'env.ts'
//...
ServiceWorkerModule.register('/ngsw-worker.js', { enabled: enablePwa })

Upvotes: 3

Dean Friedland
Dean Friedland

Reputation: 803

Below is the code for the solution I finally came up with. Hope this help someone that ever runs into this type of issue. Essentially, I just modified my environment file so that it did not create an instance of the Environment class. I guess Angular no likey the instantiation:

export const environment = {
  production: true,
  prospectBuilderModel: {
    buildQuote: false,
    buildAcknowledge: false,
    buildOrganizationInfo: false,
    buildFinancialInfo: false,
    buildTradeInfo: false,
    buildPermissiblePurpose: false,
    buildUserSetup: false,
    buildPackageSelection: false,
    buildPaymentOptions: false,
    buildOrderOptions: false,
    buildVerifyOrganizationInfo: false,
    buildDocusignAuthorization: false,
    buildDocusignContract: false
  }
}

Upvotes: 0

Arjun Shankar
Arjun Shankar

Reputation: 231

I am assuming that your code was working before you added the line ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production })

Normally when we access the environment variable in app module, it usually refers to the environment files auto-generated by angular cli (which are basically constants and exported as such). I have never tried creating an object of a class and passing it off in app module. This might be causing the problem.

Just try passing a true directly in this line instead of getting it from an object and see if that works.

Upvotes: 0

Related Questions