I followed AWS's AppSynch tutorial and successfully setup the sample Todo project from the tutorial. Now I'm trying to apply the same steps with a different schema to work with my project. I edited the schema, deployed the API and was able to make several test queries and mutations with both the AppSynch console and a mock API.
I'm running into problems with connecting my API to my front end though. I'm getting errors for all of my API request. The only thing that I changed in my process was that I edited the schema so I'm not sure if that is where I made a mistake. Since the test queries / mutations were successful does that mean my API is likely fine and the issue exist within my code? Is it necessary that I pay for an AWS support plan to work through this issue?
I'm new to AWS and GraphQL so some of the information that I provided below might be overkill. If I need to add any additional information I will be happy to. I appreciate your help and thank you for your time!
listEntries
error:
TypeError: Cannot read properties of undefined (reading 'items')
createEntry
error:
The variables input contains a field name 'entry' …defined for input object type 'CreateEntryInput'
Tutorial reference:
mutations.js:
export const createEntry = /* GraphQL */ `
mutation CreateEntry(
$input: CreateEntryInput!
$condition: ModelEntryConditionInput
) {
createEntry(input: $input, condition: $condition) {
id
content
title
topic
createdAt
updatedAt
}
}
`;
queries.js:
export const listEntries = /* GraphQL */ `
query ListEntries(
$filter: ModelEntryFilterInput
$limit: Int
$nextToken: String
) {
listEntries(filter: $filter, limit: $limit, nextToken: $nextToken) {
items {
id
content
title
topic
createdAt
updatedAt
}
nextToken
}
}
`;
schema.graphql:
type Entry @model {
id: ID!
content: String!
title: String
topic: String!
}
React.js Code:
import React, { useRef, useState, useEffect } from 'react';
import { Editor } from '@tinymce/tinymce-react';
import awsExports from "../aws-exports";
import { withAuthenticator} from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';
import { Amplify, API, graphqlOperation } from 'aws-amplify'
import { createEntry} from '../graphql/mutations.js';
import { listEntries } from '../graphql/queries.js';
Amplify.configure(awsExports);
const initialState = { id: 0, entry: '', title: '', topic: '', date:''}
export default function App() {
const [formState, setFormState] = useState(initialState)
const [entryContent, setEntry] = useState([]
useEffect(() => {
fetch()
}, [])
async function fetch() {
try {
const entryData = await API.graphql(graphqlOperation(listEntries))
const entryContent = entryData.data.list.items
setEntry(entryContent)
} catch (err) { console.log(err) }
}
function setInput(key, value) {
setFormState({ ...formState, [key]: value })
}
async function addEntry() {
try {
const entry = { ...formState }
setEntry([...entryContent, entry])
setFormState(initialState)
await API.graphql(graphqlOperation(createEntry, {input: entry}))
} catch (err) {
console.log(err)
}
}
const editorRef = useRef();
const [entryArray, setEntryArray] = React.useState(); // ORIGINAL
//const updatedList = [...entryArray]
const log = () => {
if (editorRef.current) {
setEntryArray(editorRef.current.getContent());
setInput('entry', entryArray )
addEntry()
}
};
return (
<>
<Editor
onInit={(evt, editor) => editorRef.current = editor}
initialValue='<p>This is the initial content of the editor.</p>'
disabled = {false}
inline = {false}
init={{
selector: "#entryEdi",
height: 500,
menubar: false,
placeholder: "Whats on your mind?",
plugins: [
'advlist', 'autolink', 'lists', 'link', 'image', 'charmap', 'preview',
'anchor', 'searchreplace', 'visualblocks', 'code', 'fullscreen',
'insertdatetime', 'media', 'table', 'code', 'help', 'wordcount'
],
toolbar: 'undo redo | blocks | ' +
'bold italic forecolor | alignleft aligncenter ' +
'alignright alignjustify | bullist numlist outdent indent | ' +
'removeformat | help',
content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }'
}}
/>
<button onClick={log}>Log editor content</button>
</>
);
}
Test Queries:
Amplify mock api:
For the listEntries ERROR: Instead of what you have it should be :
const entryContent = entryData.data.listEntries.items
.The items are usually stored in an object with a similar name to the query so if you check Appsync you'll see it looks like
{data{lisEntries{items{....}}}}
For the createEntry ERROR: Your initalState has a field entry, which isn't really in the schema, you can only add or get items from fields defined in the schema So your either update your schema to add the entry field or make it look like what is in the schema like this:
const initialState = { id: ", content: '', title: '', topic: ''}
Any field you want to send back to your DB should already be present in the schema. You can update the schema by adding the fields you want to add. Then run amplify push api
. That will fix it