4

I'm making an app using Gmail API. In order to send a reply to a thread, I need to get Message-ID and References headers from original message. And then these headers will be included in reply message. So before sending a reply, I'm fetching these headers from Gmail API. Headers are being fetched successfully but my code does not wait for them to be fetched and sends the reply. How can I wait for fetching call to complete. I've used promises but as I'm beginner in angularJS, I don't think I implemented them correctly. Please guide me to correct my code. Thanks.

public getReplyMessage(userId, messageId):Promise<any> {

    var headersToReturn = {
        'MessageID' : '',
        'References' : '',
    }

    gapi.client.load('gmail', 'v1', () => {
        var request = gapi.client.gmail.users.messages.get({
            'userId': userId,
            'id': messageId,
            'format': 'metadata',
            'metadataHeaders': [ 'Subject','References','Message-ID' ]
        });
        request.execute((message) => {

            var headers = message.payload.headers;

            $.each(headers, ( name , value ) => {
                if(name == 'Message-ID'){
                    headersToReturn.MessageID = value;
                }
                else if(name == 'References'){
                    headersToReturn.References = value;
                }
            });


        });
    });
    return Promise.resolve(headersToReturn);
}

And here is the code to call that function.

this.gmailApiService.getReplyMessage('me', this.MsgId).then((msgHeadersForReply) => {
        this.MessageIDHeader = msgHeadersForReply.MessageID;
        this.ReferencesHeader = msgHeadersForReply.References;
    });
    console.log("MsgIDHeader => "+this.MessageIDHeader); // this logs empty string.

Any help will be highly appreciated. Thanks :)

4
  • you are talking about Typescript. Are you using Angular version 2 or more ? The "AngularJS" name is really reserved for the first version of Angular, which was not using Typescript as far as I know. If this is a mistake, please edit and retag your question accordingly, that will help it being better received. Commented Aug 10, 2018 at 13:34
  • edited and reTagged. Thanks for suggesting. Commented Aug 10, 2018 at 13:35
  • Do you try it using Observable.zip ? Commented Aug 10, 2018 at 13:38
  • @wrivas as i mentioned I'm beginner in angular, so don't know much about it. can you please edit my code using Observable? if possible. Commented Aug 10, 2018 at 13:39

1 Answer 1

4

You are working with Promise, so no need Observables here.
From what I see is that your console.log() stands outside the Promise, So it is NULL indeed.

this.gmailApiService.getReplyMessage('me', this.MsgId).then((msgHeadersForReply) => {
        this.MessageIDHeader = msgHeadersForReply.MessageID;
        this.ReferencesHeader = msgHeadersForReply.References;
        console.log("MsgIDHeader => "+this.MessageIDHeader); // <-- move it inside 
    });

You just have to move the log inside the promise, so only when the resolved result returned, You actually have the result and there you can access its values.

Also, if you have more code to process and you want to structure it that way, you can keep chaining the then() so each level, wait for the previous.

getReplyMessage()
.then(results => ... )
.then(() => console.log())

and so on.



After you comment, your problem is in the Promise, and not in the return. try this:

public getReplyMessage(userId, messageId) {
 return new Promise((resolve, reject) => {
    var headersToReturn = {
        'MessageID': '',
        'References': '',
    }
    gapi.client.load('gmail', 'v1', () => {
        var request = gapi.client.gmail.users.messages.get({
            'userId': userId,
            'id': messageId,
            'format': 'metadata',
            'metadataHeaders': ['Subject', 'References', 'Message-ID']
        });
        request.execute((message) => {

            var headers = message.payload.headers;

            $.each(headers, (name, value) => {
                if (name == 'Message-ID') {
                    headersToReturn.MessageID = value;
                } else if (name == 'References') {
                    headersToReturn.References = value;
                }
            });
            resolve(headersToReturn)
        });
    });
 });
}
Sign up to request clarification or add additional context in comments.

6 Comments

@Asadullah try the edit. Im not familiar with this gapi and what it returns, but I tried to make sure that it resolve only after the new data updated.
@dAxx_: The resolve needs to be inside the innermost callback. You had it one callback further out, which means it would be called before request.execute completed.
@DarkFalcon good catch, too much parentheses heh, I would transform it to async/wait, but i didnt want to get into that right now.
@dAxx_ Tried your edit too. But still returning empty string. if I console.log in request.execute then it shows data correctly. You think I'm calling that promise correctly?
if you tried my edited (after the edit of Falcon) it should work, especially if its work when you console log in the same place. Add a catch to catch any error, maybe something is failed in between, and check the result.
|

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.