Angular Access data from Service

前端 未结 3 505
猫巷女王i
猫巷女王i 2021-01-26 11:52

I\'m using angular 5 and httpclient. I\'m not a big fan of the built in environments to set up my environment api url\'s that I need to consume. I have switched to using an ngin

相关标签:
3条回答
  • 2021-01-26 12:40

    For something like this you should use an app initializer service. An app initializer runs before everything else in your application and your app won't load until it's done. It's structured like this:

    import { Injectable, APP_INITIALIZER } from '@angular/core';
    
    export interface AppConfig {
        api1: string;
        api2: string;
    }
    
    @Injectable()
    export class ConfigService {
      protected config: AppConfig;
    
      constructor(private _http: HttpClient) {
      }
    
      getConfigData(): Observable<any> {
        return this._http.get<AppConfig>('... your config url...')
          .catch(error => {
            alert('Unable to read configuration file:' + JSON.stringify(error));
            return Observable.throw(error);
          });
      }
    
      public load() {
         return new Promise((resolve, reject) => {
           this.getConfigData()
             .subscribe(
               config => {
                 this.config= config ;
                 resolve(true);
               },
               err => resolve(err)
             );
         });
      }
    }
    
    export function ConfigServiceInitFactory(configService: ConfigService) {
      return () => configService.load();
    }
    
    export const ConfigServiceInitProvider = {
      provide: APP_INITIALIZER,
      useFactory: ConfigServiceInitFactory,
      deps: [ConfigService],
      multi: true
    }
    

    then you add the ConfigServiceInitProvider to your AppModule providers along with the ConfigService (put ConfigService before ConfigServiceInitProvider) and just inject the ConfigService where needed and access the config values like:

    constructor(private _config: ConfigService) {
        this.apiBase = this._config.config.api1;
    }
    

    I don't like the repetitiveness of the _config.config so i also will usually define getters on my config service like:

    get api1() { return this.config.api1 }
    

    and then you can just call:

    this.apiBase = this._config.api1;
    

    HOWEVER, if you're asking if it's possible to set values in a constants.ts file so that it can be used like:

    import {Constants} from 'app/constants';
    
    constructor() {
       this.apiBase = Constants.api1;
    }
    

    that cannot be done with something loaded from your server at runtime, because all your typescript is compiled to javascript when you run your build commands. So you logically can't create your build with something loaded from the server without it being provided as a service value. You will always have to inject a service.

    The only way around this is to insert a different constants file PRIOR to running your build, then you never need to call your config from your server. But this has drawbacks of it's own such as it requiring a full rebuild and redeploy to update config values which is kind of against the point of a config in the first place.

    0 讨论(0)
  • 2021-01-26 12:50

    You should be having the constant class as an @Injectable and have methods to set the value as below

    @Injectable()
    export class Constants {    
    
       api1 :string; // NEED API1 URL FROM SERVICE HERE;
    
       api2: string; // NEED API2 URL FROM SERVICE HERE
    
    
       setValueApi1(val){
           this.api1 = val;
       }
    }
    

    You can inject this to the constructor and call the method to set the value by passing the response as below

    @Injectable()
    export class ConfigurationService {
    private baseUrl = 'https://someUrl.com';
    
    constructor( private http: HttpClient,private constants:Constants ) {  }
    
        getConfig(): Observable<any> { 
          return this.http
          .get(this.baseUrl + '/config')
          .map(res=>res)
        }
    }
    

    In your component you can subscribe to the response value and set the api value by calling the method as below

    this.getConfig().subscribe(response => {
        this.constants.setValueApi1(response))
    })
    
    0 讨论(0)
  • 2021-01-26 12:50

    A simple way to do it is like this:

    class Constants {
        public api1: string;
        public api2: string;
    
        public setApi1(api: string) {}
        public setApi2(api: string) {}
    }
    
    export const CONSTANTS: Constants = {
        api1: "DEFAULT API 1",
        api2: "DEFAULT API 2",
        setApi1(api: string) : void {
            this.api1 = api;
        },
        setApi2(api: string) : void {
            this.api2 = api;
        }
    }
    

    Then just import your const wherever you need the persistence:

    import {CONSTANTS} from "../path/to/constant.ts";
    
    0 讨论(0)
提交回复
热议问题