Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Angular Cli's environment with an imported module

I'm using angular-cli's environment variables in a module. When I import my module in another project, is it possible to use my project's environment variables at compilation and runtime ?

My module

myModule/
    src/
        /app
            my.service.ts
        /environments
            environment.prod.ts
            environment.ts
    app.module.ts
    etc.

My module's my.service.ts

import { environment } from './environments/environment';
@Injectable()
export class MyService {
    private title = environment.title;
    showTitle(): string {
        return this.title;
    }
    etc.
}

My module's environment.ts

export const environment = {
  production: false,
  title: 'My Module in dev mode'
}

My module's environment.prod.ts

export const environment = {
  production: true,
  title: 'My Module in prod mode'
}

My project

myProject/
    src/
        /app
            app.component.ts
        /environments
            environment.prod.ts
            environment.ts
    app.module.ts
    etc.

My project's AppComponent

Component({
  selector: 'app-root',
  template: `<h1>{{title}}</h1>`
})
export class AppComponent {
    title: string;
    constructor(myService: MyService) {
        this.title = myService.showTitle();
    }        
}

My project's environment.ts

export const environment = {
  production: false,
  title: 'My Project in dev mode'
}

My project's environment.prod.ts

export const environment = {
  production: true,
  title: 'My Project in prod mode'
}

Currently, when I run my project, I see My Module in dev mode, but I'd want to see My Project in dev mode.

Is there a way to import environment.ts from a relative url like import { environment } from '/src/my-app/environments/environment' ?

like image 767
Karbos 538 Avatar asked Dec 27 '16 15:12

Karbos 538


2 Answers

From what I understand is that you've a project: 'MyProject' and an external module 'MyModule' and you want to import 'MyProject' environment variables in the 'MyModule' service 'MyService'.

IMHO, From a design perspective, It's better if you pass the environment variable as an argument to 'MyService' where you intend to use it.

However, If you insist on importing it, to import both the environment variables, In your my.service.ts Try this:

import { myModuleEnvironment } from './environments/environment';
import { myProjectEnvironment } from  '../../../src/app/environments/environment

Considering your project folder structure to be:

myProject/
 myModule/
   src/
       /app
           my.service.ts
       /environments
           environment.prod.ts
           environment.ts
   app.module.ts
 src/
    /app
        app.component.ts
    /environments
        environment.prod.ts
        environment.ts
app.module.ts
etc.

More Clarification:

TypeScript import rules has same convention as nodeJS. If an import begins with a dot:

import {library} from './some/library/path';

Then it is treated as a relative path from the file that declares the import. If however it is an absolute path (e.g. importing angular2 Component):

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

So, Typescript consider this to be an external module, it goes up the file tree till it finds package.json file. Then go into the node_modules folder, and find a folder with the same name as the import (in the above example: @angular/core). Then looks in the package.json of the module for the main .d.ts or .ts file, and then loads that, or will look for a file that has the same name as the one specified, or an index.d.ts or index.ts file.

like image 181
Ahmed Abdelrahman Avatar answered Sep 20 '22 21:09

Ahmed Abdelrahman


I don't think it is possible because the imported files are scoped to the file that imports it, so you can't access this file and data from outside unless you assign it to a class variable exposed to outside components.

What I suggest is:

Option 1

Import the env file in every file that needs it, there is no problem on doing that. Three shaking will remove duplication.

Option 2

Create a service in the model that import this env file, assign the data to a variable and expose that variable trough the service. So, whe you load the model in another model, you also load the service and can access the exposed env variable.

Something like:

my.service.ts

import { environment } from './environments/environment';
@Injectable()
export class MyService {

    environmentData = environment; // HERE YOU EXPOSE THE DATA THROUGH THIS SERVICE

    private title = environment.title;

    showTitle(): string {
        return this.title;
    }
    etc.
}

Then you can use this service wherever you want the env data.

like image 41
Bruno João Avatar answered Sep 19 '22 21:09

Bruno João