Как дождаться завершения вызова api в angular и typescript

Я делаю приложение с помощью Gmail API. Чтобы отправить ответ в ветку, мне нужно получить заголовки Message-ID и References из исходного сообщения. И затем эти заголовки будут включены в ответное сообщение. Поэтому перед отправкой ответа я беру эти заголовки из Gmail API. Заголовки извлекаются успешно, но мой код не ждет их загрузки и отправляет ответ. Как мне дождаться завершения вызова? Я использовал обещания, но поскольку я новичок в angularJS, не думаю, что реализовал их правильно. Пожалуйста, помогите мне исправить мой код. Спасибо.

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);
}

А вот код для вызова этой функции.

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.

Любая помощь будет принята с благодарностью. Спасибо :)

вы говорите о Машинописи. Вы используете Angular версии 2 или выше? Имя «AngularJS» действительно зарезервировано для первой версии Angular, которая, насколько мне известно, не использовала Typescript. Если это ошибка, отредактируйте и пометьте свой вопрос соответствующим образом, чтобы его лучше восприняли.

Pac0 10.08.2018 15:34

отредактировано и помечено тегами. Спасибо за предложение.

Asad ullah 10.08.2018 15:35

Вы пробовали использовать Observable.zip?

wrivas 10.08.2018 15:38

@wrivas, как я уже упоминал, я новичок в angular, поэтому мало что знаю об этом. не могли бы вы отредактировать мой код с помощью Observable? если возможно.

Asad ullah 10.08.2018 15:39
2
4
4 316
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы работаете с Promise, поэтому Observables здесь не нужны. Из того, что я вижу, ваш console.log() находится за пределами обещания, поэтому он действительно равен NULL.

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

Вам просто нужно переместить журнал внутри обещания, поэтому только когда будет возвращен разрешенный результат, у вас действительно есть результат, и вы можете получить доступ к его значениям.

Кроме того, если у вас есть дополнительный код для обработки и вы хотите его структурировать таким образом, вы можете продолжать связывать then() так, чтобы каждый уровень ждал предыдущего.

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

и так далее.



После того, как вы прокомментировали, ваша проблема заключается в обещании, а не в возврате. попробуй это:

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)
        });
    });
 });
}

@Asadullah попробуй отредактировать. Я не знаком с этим пробелом и тем, что он возвращает, но я попытался убедиться, что он разрешится только после обновления новых данных.

dAxx_ 10.08.2018 16:02

@dAxx_: resolve должен находиться внутри самого внутреннего обратного вызова. У вас он был на один обратный вызов дальше, что означает, что он будет вызван до завершения request.execute.

Dark Falcon 10.08.2018 16:05

@DarkFalcon хороший улов, слишком много скобок, хех, я бы преобразовал его в async / wait, но я не хотел вдаваться в это прямо сейчас.

dAxx_ 10.08.2018 16:06

@dAxx_ Тоже пробовал редактировать. Но по-прежнему возвращает пустую строку. если я console.log в request.execute, тогда он показывает данные правильно. Думаешь, я правильно называю это обещание?

Asad ullah 10.08.2018 16:11

если вы попробовали отредактированный мной (после редактирования Falcon), он должен работать, особенно если он работает, когда вы консольный журнал в том же месте. Добавьте уловку, чтобы отловить любую ошибку, возможно, что-то не так, и проверить результат.

dAxx_ 10.08.2018 16:16

Да, ваше редактирование сработало. Присмотревшись к своему коду, я обнаружил, что проблема была в $.each, поскольку он возвращает массив объектов. Я перебирал только массив: | Вот почему после выполнения обещаний он все еще возвращал null. Большое спасибо за ваши старания :) Я очень признателен. Собираюсь проголосовать и принять ваш ответ.

Asad ullah 10.08.2018 16:30

Другие вопросы по теме