npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

angular-runtime-config

v16.0.0

Published

[![github version](https://img.shields.io/github/package-json/v/vdolek/angular-runtime-config/master?label=github)](https://github.com/vdolek/angular-runtime-config) [![npm version](https://img.shields.io/npm/v/angular-runtime-config)](https://www.npmjs.c

Downloads

364

Readme

Angular Runtime Configuration

github version npm version CI

TL;DR, Angular support for one deployment package for different environments with specific configurations.

Angular framework lacks support for runtime configuration management. Build-in environments structure is compiled with the deployment package, so you have to build the application for every environment. It doesn't allow you to build one package which could be deployed to different environments.

This library brings support for loading configuration in runtime. It also allows you to load multiple configuration files and merge them into one configuration object.

Playground

StackBlitz playground

Playground project

How does it work?

At the initialisation phase of Angular app request for JSON configuration file is made. The content of the file is saved into configuration object that is resolvable by dependency injection.

By default, it looks for config.json file at the app root. But it can be changed to look for any other file, or even for multiple files that will be merged into one configuration object. This way you can have some configuration parameters shared between all environments and override only the specific parameters.

It can be as simple as:

@Injectable({...})
export class SomeService {
  constructor(
    private readonly config: Configuration, // <-- look here
    private readonly http: HttpClient
  ) {}
  
  async getData(): Promise<any> {
    const baseUrl = this.config.apiUrl; // <-- look here
    var data = await this.http.get(apiUrl + '/data').toPromise();
    return data;
  }
}

Basic usage

  1. Install angular-runtime-config library.

    $ npm install angular-runtime-config
  2. Create configuration class definition with your configuration parameters.

    export class Configuration {
      readonly apiUrl!: string; // only example
      readonly apiKey?: string; // only example
      // add some other configuration parameters
    }
  3. Import AngularRuntimeConfigModule in your AppModule. You have to specify configuration class from previous step as a parameter for forRoot() method.

    import { AngularRuntimeConfigModule } from 'angular-runtime-config';
       
    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
        ...,
       
        // specify AngularRuntimeConfigModule as an import
        AngularRuntimeConfigModule.forRoot(Configuration)
      ],
      providers: [],
      bootstrap: [ AppComponent ]
    })
    export class AppModule { }
  4. Create config.json file at the root of your app.

    {
      "apiUrl": "some url",
      "apiKey": "some key"
    }
  5. Add config.json file to assets in angular.json

    ...
    "assets": [
      "src/favicon.ico",
      "src/assets",
      "src/config.json" // <-- this line
    ],
    ...
  6. Request your configuration class in any injection context.

    @Injectable({...})
    export class SomeService {
      constructor(private readonly config: Configuration) {}
    }

With this basic usage it is the responsibility of deployment to change config.json appropriately.

If you want to make your deployment simple you can make the decision what configuration file to load in runtime based on some information (for example current app URL or a query string). For that look at the code examples next.

Specifying which configuration file/files to load

Load specific configuration file

Configuration file URL can be absolute or relative to app root url.

AngularRuntimeConfigModule.forRoot(Configuration, {
  urlFactory: () => 'config/config.json'
})

Load multiple configuration files

When using multiple configuration files, files are merged in returned array order.

AngularRuntimeConfigModule.forRoot(Configuration, {
  urlFactory: () => [ 'config/config.common.json', 'config/config.DEV.json' ]
})

Don't forget to add all configuration files to assets in angular.json. You can also add whole folder.

...
"assets": [
  "src/favicon.ico",
  "src/assets",
  "src/config" // <-- adds whole folder
],
...

Load multiple configuration files based on environment

AngularRuntimeConfigModule.forRoot(Configuration, {
  urlFactory: () => {
    const env = getEnvironment(); // your defined method that provides current environment name
    return ['/config/config.common.json', `/config/config.${env}.json`]
  }
})

Example of getEnvironment() function: (it can be implemented in any way)

function getEnvironment(): string {
  switch (location.origin) {
    case 'http://localhost': return 'LOCAL';
    case 'https://dev.example.com': return 'DEV';
    case 'https://int.example.com': return 'INT';
    case 'https://www.example.com': return 'PROD';
    default: throw Error('Unexpected base URL');
  }
}

Load multiple configuration files based on environment using injector

If you need to resolve some dependencies in order to determine url of configuration files, you can use Angular Injector.

AngularRuntimeConfigModule.forRoot(Configuration, {
  urlFactory: (injector: Injector) => {
    const env = getEnvironment(injector); // your defined method that provides current environment name
    return ['/config/config.common.json', `/config/config.${env}.json`]
  }
})

Async load multiple configuration files based on environment using injector

It is even possible to implement make urlFactory asynchronous.

AngularRuntimeConfigModule.forRoot(Configuration, {
  urlFactory: async (injector: Injector) => {
    const env = await getEnvironment(injector); // your defined method that provides current environment name
    return ['/config/config.common.json', `/config/config.${env}.json`]
  }
})

Problems and solutions

  1. Injection of Configuration class does not work in APP_INITIALIZERS (error: Configuration hasn't been initialized).
    • This is because configuration is also loaded within APP_INITIALIZERS so other APP_INITIALIZERS cannot depend on Configuration class. The solution is to replace APP_INITIALIZERS with CONFIGURATION_APP_INITIALIZERS for initializers that depend (even transitively) on Configuration class.

      {
        provide: CONFIGURATION_APP_INITIALIZER,
        useFactory: (config: Configuration) => () => ...,
        deps: [Configuration],
        multi: true
      }

License

MIT © Martin Volek