1

I want to develop a file configuration of json and it is called with http get the constructor and return the value I want the config file to another component. But when return gives me value undefined.

My Config.json

[ {"urlServer": "http://localhost:56877"}]

My Config.Service

export class configService { url: string;

constructor(public _http: Http)
{
    let injector = Injector.resolveAndCreate([loggerService]);
    let logger = injector.get(loggerService);

    try {
        return this._http.get('/app/config.json',
        {
            headers: contentHeaders
        })
        .map((res: any) =>
        {
            let data = <configModel>res.json();
            this.url = data.urlServer;
            JSON.stringify(this.url);
        });
    }
    catch (ex) {
        logger.registarErros('configService', ex);
    }
}

returnConfig()
{
    return this.url;
}

Now my other Component

constructor(public _http: Http, public config: configService)
{
    this.token = sessionStorage.getItem('token');
    this.username = sessionStorage.getItem('username');
}

login(username: String, password: String)
{
    let injector = Injector.resolveAndCreate([loggerService]);
    let logger = injector.get(loggerService);

    try
    {
        alert(this.config.url);
        return this._http.post('http://localhost:56877/api/Login/EfectuaLogin', JSON.stringify({ username, password }),
        {
            headers: contentHeaders
        })
        .map((res: any) => 
        {
            let data = <authLoginModel>res.json();
            this.token = data.token;
            this.username = data.nome;
            sessionStorage.setItem('token', this.token);
            sessionStorage.setItem('username', this.username);
            return Observable.of('authObservable');
        });
    }
    catch (ex) {
        logger.registarErros('authentication', ex);  
    }

}

I no longer know how to solve the problem, I need your help, I'm not very experienced with Angular 2. Thanks very much.

1 Answers1

0

The problem here is that the config is load asynchronously. You could use something like that leveraging the flatMap operator:

@Injectable()
export class ConfigService {
  urlServer:string;

  constructor(public _http: Http) {
  }

  getConfig() {
    if (this.urlServer) {
      return Observable.of(this.urlServer);
    }

    return this._http.get('/app/config.json', {
      headers: contentHeaders
    })
    .map((res: any) => {
      let data = <configModel>res.json();
      return data.urlServer;
    }).do(urlServer => {
      this.urlServer = urlServer;
    });
  }
}

and in your component:

login(username: String, password: String) {
  return this.configService.getConfig().flatMap(urlServer => {
    this._http.post('http://localhost:56877/api/Login/EfectuaLogin',  
      JSON.stringify({ username, password }),
      {
        headers: contentHeaders
      })
      .map((res: any) => 
      {
        let data = <authLoginModel>res.json();
        this.token = data.token;
        this.username = data.nome;
        sessionStorage.setItem('token', this.token);
        sessionStorage.setItem('username', this.username);
        return data; // or something else
      });
    }
  });
}

Another approach would be boostrap asynchronously after having loaded the configuration:

var app = platform(BROWSER_PROVIDERS)
   .application([BROWSER_APP_PROVIDERS, appProviders]);

service.getConfig().flatMap((url) => {
  var configProvider = new Provider('urlServer', { useValue: urlServer});
  return app.bootstrap(appComponentType, [ configProvider ]);
}).toPromise();

See this question for the second approach:

You can go further by mixing the last approach with a CustomRequestOptions:

import {BaseRequestOptions, RequestOptions, RequestOptionsArgs} from 'angular2/http';

export class CustomRequestOptions extends BaseRequestOptions {
  merge(options?:RequestOptionsArgs):RequestOptions {
    options.url = 'http://10.7.18.21:8080/api' + options.url;
    return super.merge(options);
  }
}

See this question:

Community
  • 1
  • 1
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • Hello, i try to do this, but return me "[object object]" :/ – Ricardo Soares May 06 '16 at 11:12
  • Ou yes. You can't use Observable.of within the callback defined for the map operator. I updated ny answer accordingly... – Thierry Templier May 06 '16 at 11:18
  • But if i dont use my Observable.Of, my login doesn't work, i want to change this "this._http.post('http://localhost:56877/api/Login/EfectuaLogin', " for example "this._http.post(this.config.url+'/api/Login/EfectuaLogin'," – Ricardo Soares May 06 '16 at 11:23