Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Newsfeed] Getting a type error when using readUpdatableFragment for StoryLikeButton #285

Open
MrJackWilson opened this issue Feb 8, 2023 · 5 comments

Comments

@MrJackWilson
Copy link

I'm getting the following type error when following the guide here: https://relay.dev/docs/tutorial/mutations-updates/#step-3--call-readupdatablefragment

Argument of type 'StoryLikeButtonFragment$key' is not assignable to parameter of type 'Readonly<{ ' $data'?: unknown; $updatableFragmentSpreads: unknown; }>'.
  Property '$updatableFragmentSpreads' is missing in type 'StoryLikeButtonFragment$key' but required in type 'Readonly<{ ' $data'?: unknown; $updatableFragmentSpreads: unknown; }>'`

Here is the entire onLikeButtonClicked function:

const onLikeButtonClicked = () => {
    commitMutation({
      variables: {
        id: data.id,
        doesLike: !data.doesViewerLike,
      },
      optimisticUpdater: (store) => {
        const fragment = graphql`
          fragment StoryLikeButton_updatable on Story @updatable {
            likeCount
            doesViewerLike
          }
        `;
        const { updatableData } = store.readUpdatableFragment_EXPERIMENTAL(
          fragment,
          story
        );
        const alreadyLikes = updatableData.doesViewerLike;
        updatableData.doesViewerLike = !alreadyLikes;
        updatableData.likeCount += alreadyLikes ? -1 : 1;
      },
    });
  };
@davidmccabe
Copy link
Contributor

It might be helpful to put your code as a fork on github so that we can see the whole thing.

@ckperez
Copy link

ckperez commented Feb 22, 2023

I am stuck at the same point.

When running store.readUpdatableFragment(fragment, story) as recommended in the tutorial, I receive a type error of Property 'readUpdatableFragment' does not exist on type 'RecordSourceSelectorProxy<{}>' and a console error (on clicking like button) of:

Warning: A store update was detected within another store update. Please make sure new store updates aren't being executed within an updater function for a different update.

When running store.readUpdatableFragment(fragment, story), as this method appears to be available according to type checking, I see the type error mentioned by @MrJackWilson and the following console error (on clicking like button):

Warning: RelayModernSelector: Expected object to contain data for fragment `StoryLikeButton_updatable`, got `{"title":"Local Yak Named Yak of the Year","summary":"The annual Yak of the Year awards ceremony took place last night, and this year's winner is none other than Max, a beloved yak from the small town of Millville. Max, who is known for his friendly personality and hardworking nature, beat out stiff competition from other yaks in the region to take home the coveted title.\n \nAccording to the judges, Max stood out due to his exceptional contributions to the community. He has been used as a pac…`. Make sure that the parent operation/fragment included fragment `...StoryLikeButton_updatable` without `@relay(mask: false)`.

Problem line in fork

@comatory
Copy link

The types forces me to use readUpdatableFragment_EXPERIMENTAL method instead of readUpdatableFragment, I'm able to call readUpdatableFragment though so this is an issue with types.

But I also get error during runtime:

Warning: A store update was detected within another store update. Please make sure new store updates aren't being executed within an updater function for a different update.

When I switch to _EXPERIMENTAL method I get error:

RelayModernSelector: Expected object to contain data for fragment `StoryLikeButton_updatable`, got `{"title":"Local Yak Named Yak of the Year","summary":"The annual Yak of the Year awards ceremony took place last night, and this year's winner is none other than Max, a beloved yak from the small town of Millville. Max, who is known for his friendly personality and hardworking nature, beat out stiff competition from other yaks in the region to take home the coveted title.\n \nAccording to the judges, Max stood out due to his exceptional contributions to the community. He has been used as a pac…`. Make sure that the parent operation/fragment included fragment `...StoryLikeButton_updatable` without `@relay(mask: false)`.

@Swahvay
Copy link

Swahvay commented Feb 4, 2024

With Relay v16, The _EXPERIMENTAL is gone, so now we are left with the RelayModernSelector error happening with every use of readUpdatableFragment. The docs example (https://relay.dev/docs/tutorial/mutations-updates/#step-3--call-readupdatablefragment) is still producing the error too.

@JCMais
Copy link

JCMais commented Jun 1, 2024

The only way I could make this work was by spreading the updatable fragment on the page query itself (looks like you cannot spread it on the component fragment?), and then doing some type-casting when running it, e.g:

        const fragment = graphql`
          fragment StoryLikeButton_updatable on Story @updatable {
            likeCount
            doesViewerLike
          }
        `;
        const { updatableData } = store.readUpdatableFragment<StoryLikeButton_updatable$key>(
          fragment,
          story as any
        );
        const alreadyLikes = updatableData.doesViewerLike;
        updatableData.doesViewerLike = !alreadyLikes;
        updatableData.likeCount += alreadyLikes ? -1 : 1;

Spreading the fragment on the query is what made the warnings go away, but I did not see this being mentioned in the page.

Spreading it on the fragment causes relay to throw an error saying the updatable fragment cannot be spread on the root.

Having to spread it on the root query feels wrong to me, and makes this basically break the composability of the fragments, as now the root query has to know about all the updates on the children components.

I am still trying to figure out how to update non-scalar values tho, as it seems the TS generated setters do not include the nested fields of the linked record?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants