awslabs / aws-mobile-appsync-sdk-js

JavaScript library files for Offline, Sync, Sigv4. includes support for React Native
Apache License 2.0
921 stars 267 forks source link

Optimistic UI updates do not work for deleting values using helper methods with AWS Amplify #392

Open janhesters opened 5 years ago

janhesters commented 5 years ago

Do you want to request a feature or report a bug? Bug

Note: This issue is probably related to #390 and #350 . Only difference is this issue takes into account the feedback from @dabit3 (writing your own query).

What is the current behavior? If you try to delete an object and do so optimistically using the helpers there is an error with writeToStore.

writeToStore.js:154 Missing field title in {
  "__typename": "Todo",
  "id": "c42e71b2-3d66-4d5b-a334-880e9aad1b54",
  "version": null
}

Same warning message shows up for every other field. If you refresh the app, the todo was successfully deleted. But there is no optimistic ui update. Meaning before the refresh the object is still showing.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem.

Steps to Reproduce

  1. Create a new React app: npx create-react-app my-app && cd my-app.
  2. Initialise AWS Amplify: amplify init. Choose defaults.
  3. Add auth with defaults: amplify add auth and hit yes to all.
  4. Add api: amplify add api and edit the schema like this:
type Todo @model @auth(rules: [{ allow: owner }]) {
  id: ID!
  title: String!
  description: String
}
  1. Add the neccessary packages:
yarn add aws-appsync aws-appsync-react graphql-tag react-apollo aws-amplify aws-amplify-react
  1. Configure index.js:
import Auth from '@aws-amplify/auth';
import Amplify from '@aws-amplify/core';
import AWSAppSyncClient from 'aws-appsync';
import { Rehydrated } from 'aws-appsync-react';
import { ApolloProvider } from 'react-apollo';
// rest of the imports

import config from './aws-exports';
Amplify.configure(config);

const client = new AWSAppSyncClient({
  url: config.aws_appsync_graphqlEndpoint,
  region: config.aws_appsync_region,
  auth: {
    type: config.aws_appsync_authenticationType,
    jwtToken: async () =>
      (await Auth.currentSession()).getIdToken().getJwtToken(),
  },
});

const WithProvider = () => (
  <ApolloProvider client={client}>
    <Rehydrated>
      <App />
    </Rehydrated>
  </ApolloProvider>
);

ReactDOM.render(<WithProvider />, document.getElementById('root'));
  1. Add authenticator and graphql to App.js:
import { withAuthenticator } from 'aws-amplify-react';
import { graphqlMutation } from 'aws-appsync-react';
import gql from 'graphql-tag';
import React, { useState } from 'react';
import { compose, graphql } from 'react-apollo';

import { createTodo, deleteTodo } from '../../graphql/mutations';

const ListTodos = gql`query ListTodos {
  listTodos {
    items {
      id
      title
      description
    }
  }
}
`;

const emptyTodo = { title: '', description: '' };

function App({ createTodo, deleteTodo, todos }) {
  const [newTodo, setNewTodo] = useState(emptyTodo);

  const handleChange = e => {
    e.persist();
    setNewTodo(t => ({ ...t, [e.target.name]: e.target.value }));
  }

  const handleCreate = () => {
    createTodo({ input: newTodo });
    setNewTodo(emptyTodo);
  }

  const handleDelete = todo => {
    deleteTodo({ input: { id: todo.id } })
  }

  return (
    // inputs and button for these functions
    // mapping over todos and rendering them
    // make sure to replace null returned from the queries, 
    // otherwise the app might crash depending on how you render.
  )
}

export default withAuthenticator(compose(
  graphqlMutation(gql(createTodo), ListTodos, 'Todo'),
  graphqlMutation(gql(deleteTodo), ListTodos, 'Todo'),
  graphql(ListTodos, {
    options: { fetchPolicy: 'cache-and-network' },
    props: ({ data }) => ({
      contacts: data.listTodos
        ? data.listTodos.items
        : [],
    }),
  })
)(App));

What is the expected behavior?

There should be no warning thrown and instead the UI should update automatically with a list without the deleted object.

Which versions and which environment (browser, react-native, nodejs) / OS are affected by this issue? Did this work in previous versions?

Google Chrome on MacOS

Graig123git commented 4 years ago

@haverchuck @janhesters was this issue resolved ?