0

I have an angular service which reads a json file containing a rest fqdn and rest port ({ "restFqdn":"kuno.dev.net", "restPort":"58085" }). I want share the fqdn and port with all other http services, which get json data from a backend rest server. The fqdn and port are static after being read from the json file, but the json file can contain different values for a particular deployment.

@Injectable()
export class FileService {

    private result: Object;
    private restFqdn = '';
    private restPort = '';

    constructor(private http:Http) {

        this.result = this.getConfFile();
        console.log('FileService - constructor: ', this.result)
        this.setFqdn(this.result[0]);
        this.setPort(this.result[1]);

    }

    getConfFile() {
        return this.http.get('json/conf.json')
            .map( (res:Response) => {
                    this.result = res.json();
                    console.log('FileService - getConfFile(): ', this.result)
                    return this.result;
                }
            )
            .catch( error =>
                Observable.throw(error || 'Server error')
            );
    };

    setFqdn(value) {
        this.restFqdn = value;
        console.log('FileService - setFqdn(): ', this.restFqdn);
    }

    getFqdn() {
        return this.restFqdn;
    }

I am not sure how to share the fqdn and port with my services. I don't really think this is state information, but do I try and use an external library like ngrx/store to do this or is there some other approach that works? This is what I currently have in my RateService.ts:

    constructor(private _http: HttpClient, private _fileService: FileService) {

    this._fileService.getConfFile().subscribe (
      data => {
        this.restFqdn = data.restFqdn;
        this.restPort = data.restPort;
        this.rateApi = '/kuno/rate';
        this.rateUrl = 'http://' + this.restFqdn + ':' + this.restPort + this.rateApi;
        console.log('RateService - constructor() - restFqdn: ', this.restFqdn);
        console.log('RateService - constructor() - restPort: ', this.restPort);
      },
      err => {
        this.errorMessage = 'Error - getConfFile failed!';
      }
    );
  }

The constructor prints out the correct values from the json file for rest fqdn and rest port. However, when I execute my getRates call, the fqdn and port are undefined. What do I need to do to get the values propagated to getRates()?

 getRates(): Observable<any> {

    console.log('RateService - getRates() - getFqdn(): ', this._fileService.getFqdn()); // prints undefined

    return this._http.get(this.rateUrl)
           .do(data => {

                          console.log('RateService: getRates(): ' + JSON.stringify(data))
                       })
           .catch(this.handleError);
 }

Many thanks!

2
  • What does the constructor for the ratesService look like? Is your FileService being injected into the constructor of the ratesService? Commented Dec 11, 2017 at 3:08
  • constructor(private _http: HttpClient, private _fileService: FileService) { this._fileService.getConfFile().subscribe ( data => { this.restFqdn = data.restFqdn; this.restPort = data.restPort; this.rateApi = '/kuno/rates'; this.rateUrl = 'http://' + this.restFqdn + ':' + this.restPort + this.rateApi; }, err => { this.errorMessage = 'Error - getConfFile failed!'; this._notifyService.send(this.errorMessage, 30, 'error'); } ); } Commented Dec 11, 2017 at 6:18

1 Answer 1

1

I suspect the following:

this.setFqdn(this.result[0]);
this.setPort(this.result[1]);

What it does is gets the 0th and 1st element from the array of response and sets it, but seeing at you config.json file, the request is in this format:

{ "restFqdn":"kuno.dev.net", "restPort":"58085" }

Which isn`t an array.Also why do you need a constructor to make the Call to your config.json file, when you are doing the same in :

this._fileService.getConfFile().subscribe (
  data => {

All you need to do is following:

Create a simple class, which maps with your config request as below (Not compulsory, but it is a cleaner way to read a Config File):

export class ConfigProp {
 restFqdn: string;
 restPort: string;
}

In your FileService class try with following changes:

@Injectable()
export class FileService {
    result: ConfigProp;
    constructor(private http:Http) {
        }

        getConfFile() {
            return this.http.get('json/conf.json')
                .map( (res:Response) => {
                        this.result = res.json();
                        console.log('FileService - getConfFile(): ', this.result)
                        return this.result;
                    }
                )
                .catch( error =>
                    Observable.throw(error || 'Server error')
                );
        };
}

Rest Everything else seems fine.

Also a word of advice. Since the config file is a shared file among different services. You might need to keep it in assets folder, as the folder is meant to contain shared, configurable resources.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you and appreciate the advice on assets folder. I am still missing something because in my service, the fx getRates this.restFqdn is blank. getRates(): Observable<any> { console.log('RateService - fqdn: ', this.restFqdn); // blank return this._http.get(this.rateUrl) .do(data => { console.log('RateService: getRates(): ' + JSON.stringify(data)) }) .catch(this.handleError); }
Is getRates method in RateService.ts class?. If yes, then I dont see any reasons why the code shouldnt work. In any case, can you share the complete RateService.ts class??

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.