apollographql / apollo-link-state

✨ Manage your application's state with Apollo!
MIT License
1.4k stars 101 forks source link

@client query depends on server data #307

Open MattReimer opened 6 years ago

MattReimer commented 6 years ago

I have a case where my derived state depends on a query to the server. I realize that cache.readQuery only reads from the cache so if I haven't already run the projQuery I won't get anything back.

Sure enough I get the dreaded error:

Error: Can't find field Project({"ProjectId":1}) on object (ROOT_QUERY) {`

So how can I write my resolver with a dependency to the server data? All I have t make queries here is the cache object and that doesn't seem to have a query function attached to it?

My resolver that I use with withClientState looks like this:

import gql from 'graphql-tag'

// This is the query on which I depend
const projQuery = gql`
  query getProjectTaxes($ProjectId: Int!) {
    Project(ProjectId: $ProjectId) {
      ProjectId
      Taxonomies {
        TaxonomyId
        Meta
      }        
    }  
  }`

const resolvers = {
  Query: {
    ProjectDerived: (_obj, {ProjectId}, {cache}, info) => {
      const projQueryRes = cache.readQuery({
        query: projQuery,
        variables: { ProjectId }
      })
      /* SOME logic here using the result of projQueryRes */
      const resultOfLogic = true

      return { myVariable: resultOfLogic }
    }
  }
}
export default resolvers
hwillson commented 5 years ago

@MattReimer We're working on a new version of apollo-link-state that replaces the concept of defaults with more dynamic function based initializers. These initializer functions can be run to prime the cache in whatever way you see fit, and have access to both the cache and the instantiated Apollo Client instance. These new initializer functions can also be run at any point; they're not limited to being called when Apollo Client is instantiated or when your link chain is first constructed. To address your issue here, you could create a new initializer function that takes care of priming the cache the way you need, by running (async) your initial network query. So in other words, you can do something like:

client.addLocalStateInitializers({
  async projectTaxes(client) {
    // ... run your query, prime the cache, etc. 
  },
});

Would this work for you?

MattReimer commented 5 years ago

Yeah! I think this would be fantastic. Sounds exactly like what I need.

arif-hanif commented 5 years ago

@hwillson that makes sense.

Borales commented 5 years ago

@hwillson Hi! I've seen your "we're working on a new version of apollo-link-state" response on different issues for this repo, do you have any preview for these changes and estimated date of new release?

smolinari commented 5 years ago

me wants to know too

Scott

hwillson commented 5 years ago

@Borales @smolinari We'll have something to share hopefully very soon! The beta is almost ready; we just have a few more edge cases to address, as well as additional tests and documentation work. Most of the outstanding issues in this repository have been addressed by the new local state project (the issues in this repo that are tagged with ac-local-state-ready), so we're very close. It would be awesome to have the beta ready before GraphQL Summit (Nov. 7th), so🤞!

pabacham commented 5 years ago

@hwillson any news about release date?

tsaiDavid commented 5 years ago

@hwillson - would love to test out the beta, ran into this problem with our product

smolinari commented 5 years ago

It's November 7th. Please do give us an update about the update. :)

Scott

Borales commented 5 years ago

Looks like apollo-link-state is being merged into apollo-client (https://github.com/apollographql/apollo-client/compare/hwillson/link-state-merge)

smolinari commented 5 years ago

Ohh.. that is a lot of opinionation to be packing into the core.

Scott

Borales commented 5 years ago

https://summit-2018-apollo-client.netlify.com/ "What's next for Apollo Client" presentation slides from yesterday (there are a few words about state management - it's going to be merged into apollo-client)

pulpfree commented 5 years ago

Any news on this, ran into same problem looking for solution, even something quick and dirty to solve problem. Is there a way to use ‘client’ in resolver to make query?

simonedavico commented 5 years ago

@pulpfree the client is available in the context parameter of the resolver. I am also facing the same use case and wonder if this is the right way to go...