apollo-cache-persist icon indicating copy to clipboard operation
apollo-cache-persist copied to clipboard

Document data defaults/initialization for 3.0

Open dcecile opened this issue 5 years ago • 7 comments

When using a local client cache, it's helpful to have a default state that only gets initialized the first time the cache is created, and not when the cache is restored from persist storage.

With 3.0, this doesn't seem simple anymore.

#85 has an old example of setting up defaults:

And this workaround:

 withClientState({
      resolvers,
      cache,
      defaults: window.localStorage.length === 0 ? defaults : {},
      typeDefs
    })

But both of those code snippets are invalid in 3.0.

In #85, there's a link to Apollo Boost code, but that code has now been removed together with all of Apollo Boost.

See https://github.com/apollographql/apollo-client/pull/4338/commits/2141cdaf3c2fa6c7f9251c6c261d3a508112fcff for the explanation that neither defaults nor intializers are necessary in 3.0 because writeData is available.

I'd like a way to initialize data only once, in a way that works with apollo-cache-persist. If such a mechanism already exists, then maybe it just needs documentation.

After initializing the client, I can do a query to see if data exists in the local cache. This results in an error, as explained in https://github.com/apollographql/apollo-feature-requests/issues/1. But swallowing the error is an OK workaround for me:

        let data = undefined
        try {
            data = client.readQuery({ query })
        } catch (error) {
            console.log("No client data yet")
            console.log(error)
        }

        if (!data) {
            client.writeQuery({ query, data: initialData })
        }

dcecile avatar Nov 14 '19 20:11 dcecile

@dcecile This is something I have overlooked. I have quickly checked and in fact this is what needs to be done. Best way to do it is to:

  • Create some helper in cache persist for seeding data.
  • Add this code to README.md

Unless we will find better way I think docs will be the simplest to apply here

wtrocki avatar Nov 14 '19 21:11 wtrocki

It's very useful feature. To be honest i was expecting and sure that this feature exists, because it's just impossible to manage local state without initial data. Could you please tell, what is the recommended way to initialize now?

dilame avatar Feb 19 '20 06:02 dilame

We can provide helper in cache persist that will use read and write method to seed data. Hoping to get better answer from Apollo on this issue

wtrocki avatar Feb 19 '20 07:02 wtrocki

Is there an update to this? @dcecile Would you mind sharing more of your code to show how you implement this? I'm really having a hard time getting the initialization to work...

hatchli avatar Mar 04 '20 16:03 hatchli

@hatchli Here's how we're initializing the cache (catching the readQuery error and later running writeQuery):

    const query = gql`
        query {
            // <INSERT QUERY HERE>
        }
    `

    let cacheData = undefined
    try {
        cacheData = client.readQuery({ query })
    } catch (error) {
        console.log("No client data yet")
        console.log(error)
        cacheData = {}
    }

    let changed = false

    // <INSERT INITIALIZATION CODE HERE>

    if (changed) {
        client.writeQuery({
            query,
            data: cacheData,
        })
    }

dcecile avatar Mar 21 '20 18:03 dcecile

Hi

Do you have any public example using 3.x. All my apps still use Apollo 2.x but I would love to experiment with 3.x and see how much work is needed to support it.

wtrocki avatar Mar 21 '20 21:03 wtrocki

Sorry, I don't have public example for 3.x. Maybe someone else..?

dcecile avatar Mar 22 '20 12:03 dcecile