2

I'm new to Angular and stuck with an issue. I have a simple configuration file config.json

{
    "param1": "https://localhost:44381/odata/"
}

Also I have a service (HttpService) wich makes http requests.

import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { throwError } from 'rxjs'; 
import { catchError, retry } from 'rxjs/operators';

@Injectable()
export class HttpService{

    constructor(
        private httpClient: HttpClient
    ) { }

    // This code was taken from Angular guide
    private handleError(error: HttpErrorResponse) {
        if (error.error instanceof ErrorEvent) {
          console.error('An error occurred:', error.error.message);
        } else {
          console.error(
            `Backend returned code ${error.status}, ` +
            `body was: ${error.error}`);
        }
        return throwError('Something bad happened; please try again later.');
      };

    getData(url:string) {
        return this.httpClient.get(url)
        .pipe(
            catchError(this.handleError)
          );
    }
}

There is also ConfigService which purpose is to read config file. Here I use my HttpService.

import { Injectable } from '@angular/core';
import { HttpService } from './http.service';
import { Observable } from 'rxjs';

@Injectable()
export class ConfigService{
    private readonly configUrl: string = 'assets/config.json';

    constructor(
        private httpService: HttpService
    ) { }

    getConfig(): Observable<Object> {
        return this.httpService.getData(this.configUrl);
    }

    getConfigParam(paramName: string): string {
        let result: string = 'Initial value';  // value set for visualization only

        //this.httpService.getData(this.configUrl)
        this.getConfig()
            .subscribe((data) => result = data[paramName],
            error => this.error = error);

        if (this.error)
            return 'Some error happened'

        return result;
    }
}

In my componenet I call getConfig function to render whole config file and everything is OK. Then I try to get parameter value from config calling this.configService.getConfigParam('param1') function and it doesn't work. Function returns 'Initial value'. If I use the function code directly in component it works.

import { Component, OnInit } from '@angular/core';
import { ConfigService } from '../config.service';

@Component({
  selector: 'app-contacts',
  templateUrl: './contacts.component.html',
  styleUrls: ['./contacts.component.css']
})
export class ContactsComponent implements OnInit {
  configData: string;
  error;
  paramValue: string;

  constructor(private configService: ConfigService) { }

  ngOnInit(): void {

    // Here config file contents are written to configData variable
    this.configService.getConfig()
    .subscribe((data) => this.configData = JSON.stringify(data),
        error => this.error = error);

    // Here getConfigParam function returns undefined
    this.paramValue = this.configService.getConfigParam('param1');

    // Doing the same from component works
    this.configService.getConfig()
     .subscribe((data) => this.paramValue = data['param1'],
         error => this.error = error);
  }
}

It seems subscribe doesn't work inside service. Can't understand what's wrong. Thanks!

WorksLikeACharm
  • 384
  • 1
  • 6
  • 14
  • It works fine, but **asynchronously**. If you need access to that value, you need to access it inside the callback; that's *why* there's a callback. – jonrsharpe Feb 24 '20 at 12:41
  • 1
    please, no convert to promise. You're looking enviroments variables: https://angular.io/guide/build#configuring-application-environments or, a APP_INITIZLIZE https://stackoverflow.com/questions/49707830/angular-how-to-correctly-implement-app-initializer – Eliseo Feb 24 '20 at 15:31
  • @Eliseo thank you. Approach with APP_INITIALIZE was useful for me. – Maksym Zapara Feb 25 '20 at 14:14

0 Answers0