Skip to content

Add documentation for inserting data into the cache #2862

Closed as not planned
Closed as not planned
@hyazel

Description

@hyazel

Question

Question

With Apollo version 1.0.x, what is the best way to add a new object in the cache of the result of a query ?

Context :

I have a screen with favorite tracks and I want to update this list whenever a track has been removed or added in favorite from an another page.

A bit like this example from demystifying cache normalization.

in code it gives :

const [mutate, { data, error }] = useMutation<
    AddTodoTypes.AddTodo, 
    AddTodoTypes.AddTodoVariables
  >(
    ADD_TODO,
    {
      update (cache, { data }) {
        const newTodoFromResponse = data?.addTodo.todo;
        const existingTodos = cache.readQuery<GetAllTodos>({
          query: GET_ALL_TODOS,
        });

        if (existingTodos && newTodoFromResponse) {
          cache.writeQuery({
            query: GET_ALL_TODOS,
            data: {
              todos: [
                ...existingTodos?.todos,
                newTodoFromResponse,
              ],
            },
          });
        }
      }
    }
  )

Coming back to iOS, before the apollo version 0.x there was a method transaction.update(query: query that could do the job (example here) but now with version 1.0.x we have to make a dedicated query marked as @apollo_client_ios_localCacheMutation to write into the cache.

I have 3 queries (listed at the end) :

  • query GetFavoriteTracks($first: Int!, $after: String)
  • query GetFavoriteTracks($first: Int!, $after: String) @apollo_client_ios_localCacheMutation
  • mutation StoreUserFavoriteTracks($trackId: ID!)

How ?

I'd like to update query GetFavoriteTracks($first: Int!, $after: String) cache when mutation StoreUserFavoriteTracks($trackId: ID!) has been done.

It would go for something like this :

public func markTrackAsFavorite(trackId: String) async throws
    -> StoreUserFavoriteTracksMutation.Data.StoreUserFavoriteTrack.Track? {
  
        // Add a track to favorite
        let favoritedTrack = try await client.perform(for: StoreUserFavoriteTracksMutation(trackId: trackId),
                                 queue: DispatchQueue.global(qos: .default)).storeUserFavoriteTrack?.track

         client.store.withinReadWriteTransaction { transaction in

            // Get favorites from cache
            let favoriteTracks = try transaction.read(query: GetFavoriteTracksQuery(first: 10, after: .some(cursor))).me?.favorites.tracks

At this point if I want to write in the GetFavoriteTracksQuery apparently I have no choice than using the GetFavoriteTracksLocalCacheMutation query :

try transaction.update(GetFavoriteTracksQueryLocalCacheMutation(first: 10, after: .some(cursor))) { data in

I'm a bit stucked here to add or remove a track object from the data track list which has the following type :

[GetFavoriteTracksQueryLocalCacheMutation.Data.Me.Favorites.Tracks.Edge]

-> How can I easily take the favoritedTrack defined upper and add it to the list ?

Queries used

query GetFavoriteTracks($first: Int!, $after: String) {
    me {
        favorites {
            tracks(first: $first, after: $after) {
                pageInfo {
                    hasNextPage
                    endCursor
                }
                edges {
                    node {
                        ...TrackDetailLite
                    }
                }
            }
        }
    }
}

query GetFavoriteTracks($first: Int!, $after: String) @apollo_client_ios_localCacheMutation {
    me {
        favorites {
            tracks(first: $first, after: $after) {
                pageInfo {
                    hasNextPage
                    endCursor
                }
                edges {
                    node {
                        ...TrackDetailLite
                    }
                }
            }
        }
    }
}
mutation StoreUserFavoriteTracks($trackId: ID!) {
  StoreUserFavoriteTrack(trackId: $trackId) {
    track {
      id
      title
    }
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsFocuses on documentation changesplanned-nextSlated to be included in the next release

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions