Closed amuresia closed 4 months ago
Hi @amuresia 👋 thanks for raising this issue!
I wasn't able to reproduce the exact error message mentioned in the description but with the following reproduction code:
"use client";
import { Schema } from "@/amplify/data/resource";
import { generateClient } from "aws-amplify/api";
import { useEffect, useState } from "react";
import { Amplify } from "aws-amplify";
import amplify_outputs from "@/amplify_outputs.json";
Amplify.configure(amplify_outputs);
const client = generateClient<Schema>();
type Todo = Schema["Todo"]["type"];
export default function Home() {
const [todos, setTodos] = useState<Todo[]>([]);
const updateTodo = async () => {
const todo = todos[0];
todo.title = "updated title";
const { data, errors } = await client.models.Todo.update(todo);
if (errors) {
console.error(errors);
} else {
console.log(data);
}
};
useEffect(() => {
const sub = client.models.Todo.observeQuery().subscribe(
async ({ isSynced, items }) => {
if (isSynced) {
console.log(items);
setTodos(items);
}
}
);
return () => {
sub.unsubscribe();
};
}, []);
async function createTodo() {
const { data: todo, errors } = await client.models.Todo.create({
title: "my todo",
});
}
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<button onClick={createTodo}>create todo</button>
<button onClick={updateTodo}>update todo</button>
</main>
);
}
I get the following error when calling client.models.Todo.update()
and pass in a todo returned from observeQuery
:
It might be worth noting that the update
function is only expecting a few fields, so createdAt
and updatedAt
also shouldn't be present.
I don't think this is a bug, the shape of the data returned from queries and subscriptions isn't really meant to be passed as is to mutations. The mutations expect fields that are on the schema and for relational fields, an id
but not the relational type as an input.
I would recommend constructing the input in the shape expected by the mutation type.
Hi @chrisbonifacio, if this is the way it works by design then that's fine. It was a bit of a grey area and I thought I should raise it. I can construct new elements with just the "required" properties whenever the subscription is triggered. Thanks for taking the time to look into it!
Before opening, please confirm:
JavaScript Framework
React
Amplify APIs
GraphQL API
Amplify Version
v6
Amplify Categories
api
Backend
Amplify Gen 2 (Preview)
Environment information
Describe the bug
Items returned by subscribers are not usable out of the box if they have nested relationships that are optional. If the relationship is not defined then it is set to null and trying to use the object for an update operation requires deconstructing it first.
Expected behavior
client.models.Todo.update(updatedTodo) should return a successful response if the goal is not set.
Reproduction steps
Setup a data schema i.e. a todo and user with a has-many relationship
const
i.e.updatedTodo
and change just the title, leaving the goal as is (empty).Code Snippet
Log output
aws-exports.js
No response
Manual configuration
No response
Additional configuration
No response
Mobile Device
No response
Mobile Operating System
No response
Mobile Browser
No response
Mobile Browser Version
No response
Additional information and screenshots
No response