23

If I have an Authentication lib, with components, service, ngrx, etc... How I can access the environment of the app implementing Authentication lib? So the Auth service should knows the backend url to make the sign in stuff. So:

import { environment as env } from "@env";
@Injectable()
class AuthService {
    private endpoint = '/v1/auth';
    private backendHost = env.backendHost;

    authenticateUser(credentials) {
        return makeHttpRequestHereToBackend(this.backendHost.this.endpoint, credentials);
    }
}

No matters where the Authentication lib is implemented, the lib service knows what server to hit from the app environment who implements said lib.

Thanks!!

J0H4N_AC
  • 499
  • 1
  • 5
  • 10
  • 2
    I am also kinda stuck at this point. I have a library to do all the common tasks and it has authentication service. To use the firebase auth (api and keys), recommended way to add it to the environments which is in the application. How to use the api keys for the library and services in the library then. Confused. feel like nrwl/nx is tricky.... – Jay Sep 23 '18 at 05:23
  • 3
    From [this comment on Github Issue](https://github.com/nrwl/nx/issues/208#issuecomment-384102058) Victor Savkin recommends ussing dependency injection to solve this problem – J0H4N_AC Sep 26 '18 at 14:18

2 Answers2

42

A solution that worked for me

Create a folder named app-config under libs and add an 'index.ts` file inside app-config folder. This lib can be shared across all your apps. Add the following content inside the index.ts file

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

export const APP_CONFIG = new InjectionToken('Application config');

Open base tsconfig.json file and add the path for app-config so that it can be useful for importing into your app with @app-workspace/app-config

"paths": {
      "@app-workspace/ui": ["libs/ui/src/index.ts"],
      "@app-workspace/auth": ["libs/auth/src/index.ts"],
      "@app-workspace/utils": ["libs/utils/src/index.ts"],
      "@app-workspace/app-config": ["libs/app-config/index.ts"]
    }

Now inside your apps open the file under apps/app1/src/app/app.module.ts and make the following changes for the providers array

import { APP_CONFIG } from '@app-workspace/app-config';
import { environment } from '../environments/environment';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    AppRoutingModule,
  ],
  providers: [
    { provide: APP_CONFIG, useValue: environment}
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Here is the sample environment.ts file that is residing under app1

export const environment = {
  production: false,
  apiUrl: 'http://localhost:3000/api',
};

You can use app-config inside your shared libs as-well, for example lets say you are making api calls from within your shared lib libs/auth/src/lib/services/auth.service.ts

import { APP_CONFIG } from '@app-workspace/app-config';
import { Inject, Injectable } from '@angular/core';

@Injectable()
export class AuthService {

  constructor(
    @Inject(APP_CONFIG) private appConfig: any
  ) {
        console.log(this.appConfig.apiUrl); // This will print `http://localhost:3000/api`
    }
}

Hope this is helpful :) Also on a sidenote, you may have to restart your application if you get any error while using the imports.

Sandeep K Nair
  • 2,512
  • 26
  • 26
18

The superior approach in my opinion is to create an @environments lib. The token approach does not allow tree shaking and seems so foreign. The lib solution is relatively easy to get.

Environments workspace library

  1. nx generate library environments --directory=shared --tags="scope:shared,type:environments" --style=scss
  2. npx rimraf ./libs/shared/environments/src/lib/*.*
  3. mv ./apps/tiny-app/src/environments/*.* ./libs/shared/environments/src/lib
  4. "export * from './lib/environment';" > ./libs/shared/environments/src/index.ts
  5. npx rimraf ./apps/tiny-app/src/environments
  6. In the build architect target of the tiny-app project in angular.json, replace the fileReplacements option in the production configuration with this entry:
{
  "projects": {
    "tiny-app": {
      "architect": {
        "build": {
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "libs/shared/environments/src/lib/environment.ts",
                  "with": "libs/shared/environments/src/lib/environment.prod.ts"
                }
              ]
            }
          }
        }
      }
    }
  }
}
  1. In main.ts, replace the environment import statement with the following:
import { environment } from '@workspace/shared/environments';

Solution taken from https://github.com/LayZeeDK/nx-tiny-app-project/blob/master/README.md

Charlie-Greenman
  • 1,469
  • 1
  • 16
  • 36