简体   繁体   中英

Returning a value from within a promise

I have a service that injects a service. The child service connects to the facebook api and is suppose to return the login status of the user to the parent service. The problem I am facing is this fb api call uses a promise and I am trying to execute some logic in the parent service based on the value of the child service function call. What would be the correct way of doing this?

This is what I tried:

facebook.service.ts

Note, the below code successfully connects to the facebook api and outputs "connected" as it should**

checkLoginStatus() {
        this.FB.getLoginStatus( (response) => {
            console.log(response.status); //outputs "connected"
        });

}

However, I am trying to return the value contained within the promise's response to the parent service, so I modified the code as follows... and getting the error:

Uncaught (in promise): TypeError: Cannot read property 'getLoginStatus' of undefined

facebook.service.ts

 FB:any;

    constructor() {
        facebook().then((FB) => {
            // Initialize SDK
            FB.init({
                appId      : '1111111111111111',
                cookie     : true,  // enable cookies to allow the server to access
                                    // the session
                xfbml      : true,  // parse social plugins on this page
                version    : 'v2.8' // use graph api version 2.5
            });

            this.FB = FB;

        });
    }

    checkLoginStatus() {
        this.FB.getLoginStatus( (response) => {
           return response.status; //"connected"
        });
    }

home.service.ts

constructor(@Inject(FacebookService) private fb:FacebookService) {
    this.authenticateFacebook();
}

authenticateFacebook() {
    this.fb.checkLoginStatus().then( (response) => {
        console.log(response); //should output connected
    });
}

At the time where you're calling your service, this.FB is still undefined, as the error shows. That's because the initialization itself is asynchronous: facebook() loads the library, and only when it's loaded, this.FB is initialized. You just need to wait for this initialization to be done before using this.FB . The fix is relatively simple though:

private fbPromise: Promise<any>;

constructor() {
    this.fbPromise = facebook().then((FB) => {
        // Initialize SDK
        FB.init({
            appId      : '1111111111111111',
            cookie     : true,  // enable cookies to allow the server to access
                                // the session
            xfbml      : true,  // parse social plugins on this page
            version    : 'v2.8' // use graph api version 2.5
        });

        return FB;
    });
}

private authenticateFacebook(FB): Promise<any> {
    return new Promise((resolve, reject) => {
        FB.getLoginStatus(response => resolve(response));
    });
}

checkLoginStatus(): Promise<string> {
    return this.fbPromise
               .then(FB => this.authenticateFacebook(FB))
               .then(response => response.status);
}

Just wrap it in your own promise which you can return and in the resolve value you can specify a return value.

public authenticateFacebook(): Promise<any> {

        return new Promise((resolve, reject) => {
           this.fb.checkLoginStatus().then( response => {
                console.log(response); //should output connected
                resolve(response);
            });
        });

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM