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

@sigao/ng-app-config

v13.0.2

Published

This library is used for loading application configuration settings from a local JSON file. By loading from a JSON file, users are able to change applications settings via a build process without rebuilding the application, as is the case with Angular's

Downloads

11

Readme

NgAppConfig

This library is used for loading application configuration settings from a local JSON file. By loading from a JSON file, users are able to change applications settings via a build process without rebuilding the application, as is the case with Angular's environment variables.

NOTE: This method of managing application variables does not in any way obfuscate values from the client. Never put sensitive values in your configuration file.

Basic Usage

Install the package

Run npm install @sigao/ng-app-config

Create the configuration json

Place a file with the extension ".json" in your project. For the sake of convenience, it is recommended that you place the file directly in the "src" folder as this is where angular looks for assets by default.

Include the file in your application

By default, Angular will not recognize your configuration file as a file to be included with the package. To change this, open your angular.json file and find the "assets" property of your projects (projects > YOUR_PROJECT > architect > build > assets). Add the file path to the array like so:

 "assets": [
              "src/favicon.ico",
              "src/assets",
              "src/MY_CONFIG.json"
            ],

Import the module

Import the module as well as a path to your file. If you placed your configuration file in the 'src' folder you will not need anything else but the file name.

const pathToConfigurationFile = 'MY_CONFIG.json';

@NgModule({
  declarations: [AppComponent],
  imports: [
    NgAppConfigModule.forRoot(pathToConfigurationFile)
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Use the service

Any component/service that needs configuration settings can now inject the NgAppConfigService. The type you define for the service will be the type of the config object.

NOTE: Due to possible loss of functionality from cloning the config object, this object CAN be edited and will behave as any other singleton. It is up to you to prevent modification of this object

import NgAppConfigService from "@sigao/ng-app-config";

@Injectable()
export class MyService {

constructor(public configService: NgAppConfigService<MyConfigType>){
	console.log(configService.config)
	}
}

Post Load Configuration

Because this library is designed to configure other aspects of the system, it may be necessary to configure other services before the application finishes loading. To do this, you will need to send a configuration object to the NgAppConfig module.

The post load object

{
  // This confunction is used to convert the raw JSON object BEFORE it is provided to the service.  
  // For example, if you want to turn your configuration object into a typescript class with
  // methods, this is where you would do that.
  customConverter?: (jsonValue: any) => any,

  // [Default: true] This flag decides if the post load actions will run sequentially or in tandem. 
  // NOTE: setting this to false could seriously impact startup performance, be sure
  // you ABSOLUTELY need sequential execution before setting this to false 
  async?: boolean,

  // This array contains a list of configuration actions to be run using the configuration result.
  actions?: {

      // Injection token of the service that needs to be configured.
      provide: any,

      // This function must be a promise.  Will execute with the provided service and 
      // loaded config object AFTER customConverter has run.

      // [config]: The config object post conversion
      // [provided]: The service as provided by the injection token
      // [result?]: The resolved value of the previous action (Only provided 
      // when "async" is set to false, otherwise undefined)
      do: (config: any, provided: any, result?: any) => Promise<any | void>
  }[]
}

[Example] Tricking the AOT compiler

When compiling AOT, the Angular CLI will not like inline annonymous functions. To get around this (and make things cleaner), make a seperate file in your app folder. We'll name ours "config.ts".

config.ts

// Define the object
export const postLoad = {
    customConverter,
    async: false,
    actions: [
        {
            provide: TestService,
            do: configFunction
        }
    ]
};

// Export the functions to appease to AOT compiler
export function customConverter(val) {
    // Conversions happen here!
    return val;
}
export function configFunction(loadedConfig, service: TestService, val) {
    console.log('Should be "undefined":', val === undefined);
    return service.returnAfterWait(3000, 'A');
}

Then, import it into your app.module and send it into the module definition:

import { postLoad } from './config.ts';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    NgAppConfigModule.forRoot('test_config.json', postLoad)
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

[Example] async = true

In this example we're providing a test service with a simple function that waits a variable number of seconds then resolves some value. Because the actions will resolve async, we resolve with null as the results can't be captured. In this instance, the actions will resolve in order of shortest wait to longest wait, regardless of their order in the array.

Total load time: 3000ms + inital config load

import { TestService } from './test.service';

const postLoadAsync = {
    async: true,
    actions: [
        {
            provide: TestService,
            do: config1
        },
        {
            provide: TestService,
            do: config2
        },
        {
            provide: TestService,
            do: config3
        },
    ]
};

export function config1(loadedConfig, service: TestService) => {
    return service.returnAfterWait(2000, null).then(() => console.log('Second')); // Resolves second
}
export function config2(loadedConfig, service: TestService) => {
    return service.returnAfterWait(3000, null).then(() => console.log('Last'));  // Resolves last
}
export function config3(loadedConfig, service: TestService, val) => {
    return service.returnAfterWait(1000, null).then(() => console.log('First')); // Resolves first
}

[Example] async = false

In this example the actions will execute in sequence. Because of this, we are able to save the resolved value of the previous action and provide it to the next action in line. This should ONLY be used if your services take very little time to configure, or you're resolving immediately by returning "Promise.resolve()".

Total load time: 9000ms + inital config load

import { TestService } from './test.service';

// Define the object
export const postLoadSync = {
    async: false,
    actions: [
        {
            provide: TestService,
            do: configFunction1
        },
        {
            provide: TestService,
            do: configFunction2
        },
        {
            provide: TestService,
            do: configFunction3
        },
    ]
};

export function configFunction1(loadedConfig, service: TestService, val) {
    console.log('Should be "undefined":', val === undefined);
    return service.returnAfterWait(3000, 'A'); // Resolves first
}
export function configFunction2(loadedConfig, service: TestService, val) {
    console.log('Should be "A":', val);
    return service.returnAfterWait(3000, 'B'); // Resolves second
}
export function configFunction3(loadedConfig, service: TestService, val) {
    console.log('Should be "B":', val);
    return service.returnAfterWait(3000, 'C'); // Resolves last
}

Change Log

13.0.2 Angular 13

  • Updated to support Angular 13
  • Updated major version to match Angular major version

2.1.0 Angular 10

  • Upgraded peer dependencies to target Angular 10
  • Tested functionality against Angular 10
  • Improved unit testing

2.0.1 - 2.0.2 New org!

  • Migrated package to our company org

2.0.0

  • Refactored extranious functionality out of config service
    • Config object is now accessed using "config" property rather than "getConfig()"
    • Removed "path" property from config service
  • Added all post load functionality
  • Moved custom converter into post load configuration object rather than direct import into moduleforRoot

Additional Info

Special thanks to https://jbt.github.io/markdown-editor/ for helping me learn README markdown.

Powered By Sigao

This package is designed to be used within our tech stack to support our development efforts. While significant effort has been made to ensure that these packages are tested and maintained, mistakes happen, and there is a good possibility the bug won't be addressed unless it directly impacts our specific use case.

If you encounter a bug that you'd like addressed, feel free to reach out to us and we'll see what we can do