Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Computed fields on a GraphQL Schema or Query with Apollo Client

I have a GraphQL query that returns two fields, titleDe and titleFr, representing a title of a post in two different languages.

I would like to have a third field on client-side (so probably local state defined) to store the title for the current language in title. My application should then be able to always call title only and get the title in the current language.

Is there an equivalent of computed fields in Apollo (Local State) or GraphQL which would allow me to call title, which checks what locale is set globally in Apollo Local State (so another query) and then return titleDe or titleFr based on that?

I didn't work that much with GraphQL and Apollo yet. I know how to solve this in other local state managers e.g. NgRx, Vuex, Redux with the concept of getters/selectors.

My goal is to abstract the titleDe/Fr logics from my applications components., so they don't require the model with all language properties and can only call the simplified title property, which will return the correct string based on the global set locale.

like image 814
René Stalder Avatar asked Sep 15 '25 11:09

René Stalder


1 Answers

You can add additional fields easily using Apollo local state. From the docs:

Local resolvers are very similar to remote resolvers. Instead of sending your GraphQL query to a remote GraphQL endpoint, which then runs resolver functions against your query to populate and return a result set, Apollo Client runs locally defined resolver functions against any fields marked with the @client directive.

Here's a simple example:

const GET_LOCALE = gql`
  query GetLocale {
    locale @client
  }
`;

const client = new ApolloClient({
  cache,
  link,
  resolvers: {
    Article: { // or whatever your actual type is called
      title: (article, _args, { cache }) => {
        const { locale } = cache.readQuery({ query: GET_LOCALE });
        switch (locale) {
          case 'de': return article.titleDe
          case 'fr': return article.titleFr
        }
      },
    },
  },
});

// Initialize the cache after creating it
cache.writeData({
  data: {
    locale: getPreferenceOrProvideDefault(),
  },
});

Here we store locale in local state as well, and use readQuery to fetch it inside our resolver. However, you could also directly fetch the preference from somewhere else (like localStorage) instead.

Note that you will still need to request these fields as part of your query -- i.e. your title field will not be expanded to the appropriate set of server-side fields.

like image 184
Daniel Rearden Avatar answered Sep 17 '25 20:09

Daniel Rearden



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!