0

I need to replace a service with a mock service depending on an environment variable. To do this, I used the ?-operator in the provider area within my module like this:

@NgModule({
  imports: [
    ...
  ],
  providers: [
    ...
    environment.e2e ? { provide: MyService, useClass: MyServiceMock} : MyService
  ],
})
export class DemoModule {
}

This approach works so far - if the 'e2e' variable is true the mock is used, otherwise the real service is loaded. There is a problem with this solution, however. If I build in production mode (with e2e=false), then the code of the mock is still included in the compiled bundle. I tried also to replace the Service via factory inside the injectable decorator. When using this solution, the service gets replaced in the right way, but the mock is again present in production bundle.

@Injectable({
  providedIn: 'root',
  useFactory: (dep1, dep2) => environment.e2e ? new MyServiceMock(dep1, dep2) : new MyService(dep1, dep2),
  deps: [dep1, dep2]
})
export class MyService {
...
}

Does anyone know a way how I can replace the service depending on the environment and the mock service also doesn't end up in the production bundle?

F. Scholz
  • 45
  • 4

1 Answers1

0

It feels like the problem of a runtime build variable initialization. If you change environment.e2e to the final value, like true or false, then it works as expected.

For that reason I found only one solution to prevent unuseful code in the final bundle: changes to the angular.json build configurations. You can do file replacements here and it works as you needed:

"fileReplacements": [
  {
    "replace": "src/app/services/my-service.service.ts",
    "with": "src/app/services/mocks/my-service-mock.service.ts"
  },
  ...
],
Anton Marinenko
  • 2,749
  • 1
  • 10
  • 16
  • In the meantime, I have also implemented the solution with file-replacement. Regarding your hint about the final value: My environment looks like this: `export const environment = { production: true, e2e: false, };` I thought defining it as const would be enough for the compiler to recognize the variable as immutable. – F. Scholz Dec 05 '22 at 09:35