houdini icon indicating copy to clipboard operation
houdini copied to clipboard

Add __id field to resolve object IDs at runtime

Open nquirmbach-ebiz opened this issue 2 years ago • 1 comments

Describe the bug

I've noticed that list operations are not working in a current project. Since I can't share the source code, I've created a sample project to reproduce the issue.

Severity

serious, but I can work around it

Steps to Reproduce the Bug

  1. Install dependencies
  2. Start application
  3. Select user
  4. Add a todo item

Expected Behaviour

The item appears in the list below.

Reproduction

https://github.com/nquirmbach-ebiz/houdini-playgrund

nquirmbach-ebiz avatar Jul 12 '23 09:07 nquirmbach-ebiz

Thanks for putting the reproduction together! I took a look and it seems like the reason the mutation isn't working is because the field that has been tagged with @list doesn't have an ID. I'm surprised to hear that ever worked but that's okay.

The best way to solve this is something that Houdini doesn't yet support so I am going to change the title a bit to reflect the feature. Let's use the query from your reproduction as an example

query UserTodos {
		users {
			data {
				id
				name
				todos {
					data @list(name: "User_Todos") {
						id
						title
						completed
					}
				}
			}
		}
	}

todos is an object with data as a field. There is no key for the object value of todos, and so the id of the parent is not being correctly computed.

The solution is to have houdini augment the schema definition for every objec type to have an __id field that the cache would resolve as a special case to encode the correct ID. You would pass to a new directive that functions similarly to @parentID but instead circumvents all of the indirect lookups:

query UserTodos {
		users {
			data {
				id
				name
				todos {
					data @list(name: "User_Todos") {
						__id
						id
						title
						completed
					}
				}
			}
		}
	}
mutation AddTodo($input: CreateTodoInput!, $listId: ID!) {
	createTodo(input: $input) {
		...User_Todos_insert @listID(value: $listId)
	}
}

export let data: PageData;

$: ({ UserTodos: store } = data);

async function add() {
  await addMutation.mutate({
	  listId: $store.data.users?.data.todos?.data.listId,
	  input: {
		  completed: false,
		  title
	  }
  });
}

If this is something you have the time and energy to implement, let me know and I can provide whatever guidance is necessary

AlecAivazis avatar Jul 18 '23 06:07 AlecAivazis