2

I am trying to share the result of an http request from the following service with multiple components. The problem I am experiencing, is that each component's request for the getMe() function creates a new http call. The MeService service is only declared as a provider in the root module of the page, and imported in each *.component.ts, so this is not caused by the (common) mistake of redeclaring the service multiple times as a provider in all child components. As you'll be able to tell from the output, it is most likely caused due to the async nature of the call, but correct me if I'm wrong.

Here is the service code:

import { Injectable } from '@angular/core';
import { Headers, Http } from '@angular/http';

import 'rxjs/add/operator/toPromise';

@Injectable()
export class MeService {

    private apiUrl = 'api/get/me';

    private me: Object;

    constructor(private http: Http) { }

    getMe(): Promise<Object> {

        console.log("OBSERVATION 1: " + this.me);

        if (this.me) {

            //Not sure if this is correct or not, I've never reached this block yet
            return Promise.resolve(this.me)

        } else {

            return this.http.get(this.apiUrl)
                .toPromise()
                .then(response => {

                    console.log("OBSERVATION 2: " + this.me);

                    this.me = response.json();

                    console.log("OBSERVATION 3: " + this.me);

                    return this.me
                })
                .catch(this.handleError);

        }
    }

    //Not relevant, just for completeness
    private handleError(error: any): Promise<any> {

        console.error('An error occurred', error); // for demo purposes only
        return Promise.reject(error.message || error);

    }
}

The output in the console. Mind that the [object Object] are filled with the correct data, I have checked this and omitted the JSON.Stringify() for clarity.

OBSERVATION 1: undefined

OBSERVATION 1: undefined

OBSERVATION 2: undefined

OBSERVATION 3: [object Object]

OBSERVATION 2: [object Object]

OBSERVATION 3: [object Object]

What I believe is happening, is that the Angular components are loaded before any http call has returned, causing multiple requests at bootstrapping. What would be the correct and best way of mitigating this?

2 Answers 2

2

Try returning the request itself and performing the operation inside your component. Do you have to use promises? Angular prefers observables.

return this.http.get(this.apiUrl).map(res => res.json());

Then subscribe in each of your components.

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

1 Comment

0

Thanks to the hint from chrispy, I dove into Observables and it appears that they indeed are the preferred way of implementing async http calls. However, merely subscribing from within the components did not prevent multiple calls from the service to the API, I didn't get it to work until I found this answer. I'm not sure whether it is a best practise, but it works.

Comments

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.