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 Answer 1

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:

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

3 Comments

Hello, i try to do this, but return me "[object object]" :/
Ou yes. You can't use Observable.of within the callback defined for the map operator. I updated ny answer accordingly...
But if i dont use my Observable.Of, my login doesn't work, i want to change this "this._http.post('localhost:56877/api/Login/EfectuaLogin', " for example "this._http.post(this.config.url+'/api/Login/EfectuaLogin',"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.