Как использовать optimisticResponse в Apollo Angular с refetchQueries

Я пытаюсь использовать оптимистичный пользовательский интерфейс Apollo, но не могу заставить его работать должным образом. Чтобы проверить это, я установил точку останова на сервере, чтобы можно было задержать ответ. Я ожидал увидеть результат изменения в списке, но все это ждет ответа от сервера. Что я делаю неправильно?

Это Angular 7, клиент Apollo-angular 2.4.0 для Angular:

"apollo-angular": "^1.5.0",
    "apollo-angular-link-http": "^1.6.0",
    "apollo-cache-inmemory": "^1.3.2",
    "apollo-client": "^2.4.0",
    "apollo-link": "^1.2.11",
    "apollo-link-error": "^1.1.10",

Чтобы узнать, находится ли элемент в кеше, я сначала вызвал его, и он, как и ожидалось, возвращает идентификатор:

let testID = defaultDataIdFromObject(mail); 
console.log('found in cache: ', testID); // outputs the correct ID 
(e.g. found in cache)

Вывод в консоль:

Электронная почта: Cl4weDliM2QyZjQ1OTU2ZTZlMmZmOTAyMjRkYTkxNmE2MjI1ZDk2NWM3MDcAAAFrAUPhyTB4OWIzZDJmNDU5NTZlNMUyZmY5MDIyzotRh

Это полный запрос:

this.trashEmailGQL.mutate({
      id: mail.id,
      table: Table.ARCHIVE
    },{
      refetchQueries: [{
        query: this.getEmailsGQL.document,
        variables: {table: Table.ARCHIVE}
      },
      {
        query: this.getEmailsGQL.document,
        variables: {table: Table.TRASH}
      }],
      optimisticResponse:{
        __typename:'Mutation',
        trashEmail:{
          __typename:"Email",
          id:mail.id,
          fromEmail:mail.fromEmail,
          fromName:mail.fromName,
          fromAddress:mail.fromAddress,
          cc: mail.cc,
          bcc: [],
          replyTo:mail.replyTo,
          body:mail.body,
          contentType:mail.contentType,
          draftId:"",
          read:mail.read,
          inReplyTo:mail.inReplyTo,
          inReferences:mail.inReferences,
          created:mail.created
        }
      }
    }).subscribe(({data}) => {
      console.log('Trashed email response: ', data);
    }, (err) => {
      this.errorService.handleError(err);
    });

Я ожидал, что Apollo вернет результаты из кеша и обновит таблицу до того, как сервер вернет какой-либо ответ.


person Igor    schedule 29.05.2019    source источник


Ответы (1)


Наконец разобрался. Apollo 2.x не поддерживает удаление мутаций из коробки. Поэтому необходимо выполнить ручное удаление из кеша. Решение выглядит не очень хорошо (взрыв кода), но в настоящее время оно лучше, чем бросание камня в спину.

Предположительно версия 3.x должна решить эту проблему, но в настоящее время это решение, которое я нашел, работает, как и следовало ожидать.

this.trashEmailGQL.mutate({
      id: mail.id,
      table: Table.ARCHIVE
    },  
    {
        refetchQueries: [{
          query: this.getEmailsGQL.document,
          variables: {table: Table.ARCHIVE}
        },
        {
          query: this.getEmailsGQL.document,
          variables: {table: Table.TRASH}
        }], 
        optimisticResponse:{
          __typename:'Mutation',
          trashEmail:{
            __typename:"Email",
            id:mail.id,
            fromEmail:mail.fromEmail,
            fromName:mail.fromName,
            fromAddress:mail.fromAddress,
            cc: mail.cc,
            bcc: [],
            replyTo:mail.replyTo,
            body:mail.body,
            contentType:mail.contentType,
            draftId:"",
            read:mail.read,
            inReplyTo:mail.inReplyTo,
            inReferences:mail.inReferences,
            created:mail.created
          }
        },
        update: (store, {data :{trashedEmail}}) => {
          const data = store.readQuery({query: this.getEmailsGQL.document, variables: {table: Table.ARCHIVE}});
          if (data && data.hasOwnProperty('getEmails')) {
            let cacheList:Email[] = data['getEmails'];
            let foundItemIndex = cacheList.findIndex(i => i.id === mail.id);
            if (foundItemIndex > -1) {
              cacheList.splice(foundItemIndex,1)
              data['getEmails'] = cacheList
              store.writeQuery({query: this.getEmailsGQL.document, variables: {table: Table.ARCHIVE}, data:data});
            }
          }
        }
      }
     ).subscribe(({data}) => {
      console.log('Trashed email response: ', data);
    }, (err) => {
      this.errorService.handleError(err);
    });
person Igor    schedule 30.05.2019