19

I am using <Mutation /> component which has Render Prop API & trying to do Optimistic Response in the UI.

So far I have this chunk in an _onSubmit function -

createApp({
    variables: { id: uuid(), name, link },
    optimisticResponse: {
        __typename: "Mutation",
        createApp: {
            __typename: "App",
            id: negativeRandom(),
            name,
            link
        }
    }
});

And my <Mutation /> component looks like -

<Mutation
    mutation={CREATE_APP}
    update={(cache, { data: { createApp } }) => {
        const data = cache.readQuery({ query: LIST_APPS });
        if (typeof createApp.id == "number") {
            data.listApps.items.push(createApp);
            cache.writeQuery({
                query: LIST_APPS,
                data
            });
        }
    }}
>

{/* 
some code here
*/}

</Mutation>

I know that update function in <Mutation /> runs twice, once when optimisticResponse is ran & second time when server response comes back.

On the first time, I give them id as a number. Checkout createApp in optimisticResponse where id: negativeRandom()

That's why my update prop in <Mutation /> component has a check if createApp.id is a number then push it in the array. It means that if data returned from local then push it in local cache & if returned from server don't push it.

But what happens is the data is only showed when returned from the server. The function update runs twice but it does not push it in the array.

I think there might 3 problems -

  1. Either the update function does not run when local state is pushed

  2. I've tried making fetchPolicy equal to cache-and-network & cache-first but it didn't work too.

  3. The __typename in optimisticResponse. Idk if Mutation is the correct value, so I tried AppConnection too but it still does not work.

The complete code can be found here. Whole code exist in one file for simplicity. Its a very simple app which has 2 inputs & 1 submit button. It looks like -

dark mode list app

Note: Same thing works with React. Here's a link to React Repo - https://github.com/deadcoder0904/react-darkmodelist

deadcoder0904
  • 7,232
  • 12
  • 66
  • 163
  • I've ran your project and it seems to be working perfectly. I changed the UI to display the id before the name and Server responses and cached optimistic UI responses are both displayed. – user3256877 Jun 05 '18 at 22:06
  • Which project? React project works. React Native does not work with Optimistic UI. It shows the item in the list 2 seconds later after the server returns response. Can you provide more details about code? I do not understand what you are saying. – deadcoder0904 Jun 06 '18 at 07:51
  • Apologies for my confusing explaination. To be clear, I ran your react native project on an iOS simulater. When connected to the internet, I added a new city and it responded from the server and displayed the server response in the list, as expected. When no connection is available, the optimistic UI works and shows the negative id. However, I've just re-read your question and realised what your actual problem is. It's not that you can't see anything when you aren't getting a response, it's that you aren't seeing anything before you get the response back, right? – user3256877 Jun 06 '18 at 22:43
  • Yes exactly. And the funny thing is same code is written in React & it works perfectly. In React Code, I've just removed the `if (typeof createApp.id === "number")` & everything is the exact same & it works while in React Native if I remove the same `if` condition I get duplicate values from Optimistic Response & Actual Mutation. So inshort, same code with slight difference. React one works without an issue & React Native doesn't work (I mean only Optimistic UI) – deadcoder0904 Jun 07 '18 at 04:42
  • Check `__typename ` of the `createApp` object returned by the mutation. It should be same type as `listApps.items` of your `listApps` query. – eronisko Jul 02 '18 at 12:01
  • Yes they are both returning `App` as their `__typename` – deadcoder0904 Jul 02 '18 at 19:57
  • @eronisko Thanks for adding a comment. I just updated my dependencies & now it works. I think it was a bug in Apollo Client or React Apollo in combo with React Native because I didn't change any code & it worked :) – deadcoder0904 Jul 02 '18 at 20:24

1 Answers1

4

Apparently this was a bug in Apollo or React Apollo package. Don't know which bug or was it just for React Native but I just updated my dependencies & solved it without changing any code

You can check out the full code at https://github.com/deadcoder0904/react-native-darkmode-list

deadcoder0904
  • 7,232
  • 12
  • 66
  • 163