Relay: Modern bug: Missing type for interface in optimisticResponse

Created on 16 Aug 2017  路  7Comments  路  Source: facebook/relay

For following mutation

const mutation = graphql`
  mutation UpdatePricesMutation($input: updatePricesInput!) {
    updatePrices(input: $input) {
        prices {
            id
            prices {
              amount
              total
              saved
            }
        }
    }
  }
`;

export default ({ pricesObject, prices }) => {
    const variables = {
        input: {
            pricesId: pricesObject.id,
            prices: prices.map(price => ({
                total: price.total,
                amount: price.amount
            })),
            clientMutationId: ''
        }
    };

    const res = commitMutation(
        environment,
        {
            mutation,
            variables,
            optimisticResponse: () => {

                return {
                    updatePrices: {
                        prices: {
                            id: pricesObject.id,
                            prices: prices.map(price => ({
                              total: price.total,
                              amount: price.amount,

                             }))
                        }
                    }
                }
            }
        }
    );
};

I am getting error:

Uncaught Error: RelayResponseNormalizer(): Expected a typename for record `{
  "id": "BP-15",
  "prices": [
    {
      "total": "5.00",
      "amount": 10
    },
    {
      "total": "30.00",
      "amount": 50
    },
    {
      "total": "60.00",
      "amount": 100
    }
  ]
}`.
    at invariant (invariant.js:44)
    at RelayResponseNormalizer._getRecordType (RelayResponseNormalizer.js:80)
    at RelayResponseNormalizer._normalizeLink (RelayResponseNormalizer.js:157)
    at RelayResponseNormalizer._normalizeField (RelayResponseNormalizer.js:144)
    at RelayResponseNormalizer.js:89
    at Array.forEach (<anonymous>)
    at RelayResponseNormalizer._traverseSelections (RelayResponseNormalizer.js:87)
    at RelayResponseNormalizer._normalizeLink (RelayResponseNormalizer.js:163)
    at RelayResponseNormalizer._normalizeField (RelayResponseNormalizer.js:144)
    at 

I have been investigating why it happens, because I used optimisticResponse with relay modern and worked fine.

And the tricky part is that the prices is graphql interface. So this node does not have concreteType, therefore it fails to derive the type. Any hint for work around would be super helpful. I also could spend some time on PR if you would push me to the right direction how to address it.

prices node looks like:
```
{
"kind": "LinkedField",
"alias": null,
"args": null,
"concreteType": null,
"name": "prices",
"plural": false,
"selections": [
...
],
"storageKey": null
}

wontfix

Most helpful comment

Ok.. workaround seems to be explicitly provided __typename in optimistic response:

optimisticResponse: () => {

    return {
        updatePrices: {
            prices: {
                id: pricesObject.id,
                __typename: 'BasePrice',
                prices: prices.map(price => ({
                  total: price.total,
                  amount: price.amount,
                 }))
            }
        }
    }

All 7 comments

Ok.. workaround seems to be explicitly provided __typename in optimistic response:

optimisticResponse: () => {

    return {
        updatePrices: {
            prices: {
                id: pricesObject.id,
                __typename: 'BasePrice',
                prices: prices.map(price => ({
                  total: price.total,
                  amount: price.amount,
                 }))
            }
        }
    }

@jardakotesovec I'm getting this error too. Is typename just the prices return type? I tried supplying this and couldn't get it to work. Although the error does go away but nothing updates.

@MartinDawson I have done some test on optimisiticResponse, using Github's graphql API. More specifically, I am using the addStar and removeStar mutations.

First, I found that for optimisticResponse to work you have to provide an id, which is not mentioned by the doc, which is confusing.

Second, for interface type (for example, Starrable from Github), you have to provide a __typename, even if you use inline fragment to query on specific type. The weird part is, the __typename need not to be accurate! You can use any string, and the optimistic update still works.

@irrigator Would you mind opening a PR to amend the documentation (and possibly a bug report for that __typename issue)?

Would like to help.

@alloy Created a related issue with sample code: #2365

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings