8

I have several settings which should be in a configuration file.

For example: URL of APIs

Where is the best place for it in Ionic 2?

sebaferreras
  • 44,206
  • 11
  • 116
  • 134
rakete
  • 2,953
  • 11
  • 54
  • 108

3 Answers3

7

From Angular 2/4 Docs:

Non-class dependencies

What if the dependency value isn't a class? Sometimes the thing we want to inject is a string, function, or object.

Applications often define configuration objects with lots of small facts (like the title of the application or the address of a web API endpoint) but these configuration objects aren't always instances of a class.

One solution to choosing a provider token for non-class dependencies is to define and use an OpaqueToken

So you would need to define a config object with the urls and so on, and then an OpaqueToken to be able to use it when injecting the object with your configuration.

I included all my configuration in the app-config.ts file

// Although the ApplicationConfig interface plays no role in dependency injection, 
// it supports typing of the configuration object within the class.
export interface ApplicationConfig {
  appName: string;
  apiEndpoint: string;
}

// Configuration values for our app
export const MY_CONFIG: ApplicationConfig = {
  appName: 'My new App',
  apiEndpoint: 'http://www...'
};

// Create a config token to avoid naming conflicts
export const MY_CONFIG_TOKEN = new OpaqueToken('config');

What OpaqueToken is may be confusing at first, but it just a string that will avoid naming conflicts when injecting this object. You can find an amazing post about this here.

Then, you just need to include it in the page you need it like this:

import { NavController } from 'ionic-angular/index';
import { Component, OpaqueToken, Injectable, Inject } from "@angular/core";

// Import the config-related things
import { MY_CONFIG_TOKEN, MY_CONFIG, ApplicationConfig } from 'app-config.ts';

@Component({
  templateUrl:"home.html",
  providers: [{ provide: MY_CONFIG_TOKEN, useValue: MY_CONFIG }]
})
export class HomePage {

  private appName: string;
  private endPoint: string;

  constructor(@Inject(MY_CONFIG_TOKEN) private config: ApplicationConfig) {
    this.appName = config.appName;
    this.endPoint = config.apiEndpoint;
  }
}

Please notice how to include it in the providers array

providers: [{ provide: MY_CONFIG_TOKEN, useValue: MY_CONFIG }]

And how to tell the injector how it should obtain the instance of the config object

@Inject(MY_CONFIG_TOKEN) private config: ApplicationConfig

UPDATE

OpaqueToken has been deprecated since v4.0.0 because it does not support type information, use InjectionToken<?> instead.

So instead of these lines:

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

// Create a config token to avoid naming conflicts
export const MY_CONFIG_TOKEN = new OpaqueToken('config');

Now we should use

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

// Create a config token to avoid naming conflicts
export const MY_CONFIG_TOKEN = new InjectionToken<ApplicationConfig>('config');
sebaferreras
  • 44,206
  • 11
  • 116
  • 134
1

Save them in a class singleton ( generally an anti-pattern) or even better Namespace equivalent.

class Singleton {
    /* ... lots of singleton logic ... */
    public someMethod() { ... }
}

// Using
var x = Singleton.getInstance();
x.someMethod();

Namespace equivalent

namespace Singleton {
    export function someMethod() { ... }
}
// Usage
Singleton.someMethod();
var x = Singleton; // If you need to alias it for some reason
user1275105
  • 2,643
  • 5
  • 31
  • 45
  • This seems much easier and readable than injecting as angular suggests. Maybe use constant static in the class – misha130 Aug 15 '16 at 17:15
  • if you use it as a providers in bootstrap(), then it is automatically singleton. Don't need to use any `getInstance()` methods. – Jagannath Aug 17 '16 at 10:17
-3

You may use either WebSQL or SQLite table or LocalStorage since both methods are very well supported by Ionic and hybrid Apps frameworks.

jjyepez
  • 352
  • 3
  • 7
  • The settings are very static. Maybe I don't have to change them anytime. So why should I use SQL? What is the advantages of it compared to a xml or json file? – rakete Aug 13 '16 at 23:20
  • Using navigator-based SQLite or WebSQL your settings will be contained and managed within the navigator context and they will be likely reseted or reinitialized as the App is managed through the settings section on the smartphone (clear cache, etc.) itself as it is supposed to be, whilst using "external" files they won't change regarding smartphone managing of the App settings change but by explicit resetting them or reinitializing them from within your program instructions which may not be the regular behavior of an app. Nonetheless you might be using whichever method fits your app the best. – jjyepez Aug 13 '16 at 23:36
  • I think you misunderstood me. I don't want to save the users settings. I want to save enviroement settings which never change when published the app. Internal settings like API url to my own server for fetching data and so on... – rakete Aug 13 '16 at 23:52
  • There is another difference you may consider: by storing settings on an external file you will have to require "storage reading/writing" permisions from the OS/user (to store several "static" values), whilst using SQL or even Localstorage you may not. – jjyepez Aug 14 '16 at 00:14