amplify-category-api icon indicating copy to clipboard operation
amplify-category-api copied to clipboard

[Amplify Gen2] Property Todo does not exist on type for a new Scaffolded Todo Gen2 project

Open ujjwol05 opened this issue 1 year ago • 15 comments

Environment information

System:
  OS: macOS 14.4
  CPU: (8) x64 Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
  Memory: 93.27 MB / 16.00 GB
  Shell: /bin/zsh
Binaries:
  Node: 20.11.0 - ~/.nvm/versions/node/v20.11.0/bin/node
  Yarn: 1.22.11 - /usr/local/bin/yarn
  npm: 10.2.4 - ~/.nvm/versions/node/v20.11.0/bin/npm
  pnpm: undefined - undefined
NPM Packages:
  @aws-amplify/backend: 0.12.1
  @aws-amplify/backend-cli: 0.11.1
  aws-amplify: 6.0.20
  aws-cdk: 2.133.0
  aws-cdk-lib: 2.133.0
  typescript: 5.4.2
AWS environment variables:
  AWS_SDK_LOAD_CONFIG = 1
  AWS_STS_REGIONAL_ENDPOINTS = regional
  AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
No CDK environment variables

Description

When attempting to retrieve data from the Todo model using client.models.Todo.list(), TypeScript throws an error indicating that the 'Todo' property does not exist on the type.

// TodoList.tsx

import type {Schema} from "@/amplify/data/resource";

// generate your data client using the Schema from your backend
const client = generateClient<Schema>();

export default function TodoList() {
    const [todos, setTodos] = useState<Schema["Todo"][]>([]);

    async function listTodos() {
        // fetch all todos
        const {data} = await client.models.Todo.list();
        setTodos(data);
    }
    ......

data/resource.ts

import { type ClientSchema, a, defineData } from '@aws-amplify/backend';

/*== STEP 1 ===============================================================
The section below creates a Todo database table with a "content" field. Try
adding a new "isDone" field as a boolean. The authorization rules below
specify that owners, authenticated via your Auth resource can "create",
"read", "update", and "delete" their own records. Public users,
authenticated via an API key, can only "read" records.
=========================================================================*/
const schema = a.schema({
  Todo: a
    .model({
      content: a.string(),
      done: a.boolean(),
      priority: a.enum(['low', 'medium', 'high'])
    })
    .authorization([a.allow.owner()]),
});

export type Schema = ClientSchema<typeof schema>;

export const data = defineData({
  schema,
  authorizationModes: {
      defaultAuthorizationMode: 'userPool'
  },
});

/*== STEP 2 ===============================================================
Go to your frontend source code. From your client-side code, generate a
Data client to make CRUDL requests to your table. (THIS SNIPPET WILL ONLY
WORK IN THE FRONTEND CODE FILE.)

Using JavaScript or Next.js React Server Components, Middleware, Server 
Actions or Pages Router? Review how to generate Data clients for those use
cases: https://docs.amplify.aws/gen2/build-a-backend/data/connect-to-API/
=========================================================================*/

/*
"use client"
import { generateClient } from "aws-amplify/data";
import { type Schema } from "@/amplify/data/resource";

const client = generateClient<Schema>() // use this Data client for CRUDL requests
*/

/*== STEP 3 ===============================================================
Fetch records from the database and use them in your frontend component.
(THIS SNIPPET WILL ONLY WORK IN THE FRONTEND CODE FILE.)
=========================================================================*/

/* For example, in a React component, you can use this snippet in your
  function's RETURN statement */
// const { data: todos } = client.models.Todo.list()

// return <ul>{todos.map(todo => <li key={todo.id}>{todo.content}</li>)}</ul>

ujjwol05 avatar Mar 17 '24 12:03 ujjwol05

Hi @ujjwol05 this might be related to https://github.com/aws-amplify/amplify-backend/issues/1069 Can you try installing the latest beta versions of @aws-amplify/backend and @aws-amplify/backend-cli and see if that resolves the issue?

edwardfoyle avatar Mar 18 '24 16:03 edwardfoyle

Hi @ujjwol05 this might be related to aws-amplify/amplify-backend#1069 Can you try installing the latest beta versions of @aws-amplify/backend and @aws-amplify/backend-cli and see if that resolves the issue?

ok upgrading helped me a bit.

The type infered for 'data' looks correct for me

 const {data} = await client.models.Todo.list()

But, Todo from the models still does not exist on the type.

const {data} = await client.models.Todo

ujjwol05 avatar Mar 18 '24 22:03 ujjwol05

@ujjwol05 - can you paste in your latest package.json?

renebrandel avatar Mar 21 '24 20:03 renebrandel

@renebrandel

{
  "name": "test",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "sandbox-delete":  "npx amplify sandbox delete",
    "sandbox":  "npx amplify sandbox"
  },
  "dependencies": {
    "@aws-amplify/ui-react": "^6.1.6",
    "aws-amplify": "^6.0.20",
    "next": "14.1.3",
    "react": "^18",
    "react-dom": "^18"
  },
  "devDependencies": {
    "@aws-amplify/backend": "^0.13.0-beta.9",
    "@aws-amplify/backend-cli": "^0.12.0-beta.10",
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "aws-cdk": "^2.133.0",
    "aws-cdk-lib": "^2.133.0",
    "constructs": "^10.3.0",
    "esbuild": "^0.20.2",
    "eslint": "^8",
    "eslint-config-next": "14.1.3",
    "tsx": "^4.7.1",
    "typescript": "^5.4.0"
  }
}

ujjwol05 avatar Mar 21 '24 22:03 ujjwol05

Hi @ujjwol05, good to know that the upgrade resolved your issue with list queries. For the other snippet you shared i.e

const {data} = await client.models.Todo

Can you clarify what is missing here? I believe in order to get the data, you should perform any operation like get or list which might be missing in your code.

phani-srikar avatar Mar 24 '24 18:03 phani-srikar

Hi @ujjwol05, good to know that the upgrade resolved your issue with list queries. For the other snippet you shared i.e

const {data} = await client.models.Todo

Can you clarify what is missing here? I believe in order to get the data, you should perform any operation like get or list which might be missing in your code.

Yes, The process of accessing type from the Todo model can be accomplished through either the get() or list() methods. However, I was expecting the functionality of client.models to provide a list of available models already ,which isn't the case for me now .Because the client.model isn't aware of the available models, As a consequence, I find myself in the position of manually typing the required models on the front end. ( no auto-completion )

ujjwol05 avatar Mar 24 '24 23:03 ujjwol05

Hi,

Below, what I did and worked for me to fix same Type issue:

  • npm install --save-dev @aws-amplify/backend@beta @aws-amplify/backend-cli@beta
  • deleted node_modules folder and file package-lock.json
  • npm install
  • in file tsconfig.json added "allowImportingTsExtensions": true, in 'compilerOptions'
  • in file app/page.tsx replaced import TodoList from "'@/app/components/TodoList.tsx'"; by import TodoList from './components/TodoList.tsx';

oldu73 avatar Mar 25 '24 06:03 oldu73

@ujjwol05 can you please try the above steps and see if that works for you as well? Thanks

phani-srikar avatar Mar 25 '24 17:03 phani-srikar

@ujjwol05 can you please try the above steps and see if that works for you as well? Thanks

Did all the steps except the last 2 steps and i have same issue.

ujjwol05 avatar Apr 05 '24 00:04 ujjwol05

For this issue was cuased by using the @latest version of libraries. Don't use the 'latest'!!! Use the 'Beta' version, thus do the followings - Either Clean up your existing project

  1. deleted node_modules folder and file package-lock.json
  2. npm install --save-dev @aws-amplify/backend@beta @aws-amplify/backend-cli@beta
  3. npm install

Or start from scractch by following this Amplify docs for Next.js App Router (Client Components) https://docs.amplify.aws/gen2/start/quickstart/nextjs-app-router-client-components/

Hope this helps!

tulsirai avatar Apr 18 '24 14:04 tulsirai

Hey @ujjwol05, This issue has been resolved in latest version, Please try upgrading your lib to below vesions and let us know if it resolves your issue?

    "@aws-amplify/backend": "^0.13.0-beta.20",
    "@aws-amplify/backend-cli": "^0.12.0-beta.22",

AnilMaktala avatar Apr 19 '24 18:04 AnilMaktala

I believe it's been (partially) fixed in the latest beta (for models), but doesn't work for custom queries/mutations. Here's my example:

// resource.ts
const schema = a.schema({
  AgentResponse: a.customType({
    name: a.string(),
  }),

  listAgents: a
    .query()
    .returns(a.ref("AgentResponse").array())
    .handler(a.handler.function(listAgentsHandler)),
});
// index.tsx
async function App() {
  // this code works, but typescript is throwing "Property 'listAgents' does not exist on type 'CustomQueries<InternalClientSchema<ModelSchema<{ types: { AgentResponse: CustomType<{ fields: { name: ModelField<Nullable<string>, never, undefined>;  }; }>; listAgents: CustomOperation<...>; ...'.ts(2339)"
  const { data: agents, errors } = await cookiesClient.queries.listAgents();

  // listAgents is however defined under models (which it shouldn't) and the below code doesn't actually work: "Error: Cannot read properties of undefined (reading 'list')"
  const { data: agents, errors } = await cookiesClient.models.listAgents.list();

  return ();
}

hardchor avatar Apr 21 '24 11:04 hardchor

The quickstart vite-react app does not build succesfully due to type error of Schema["Todo"]; I am using 1.0.0 version of @aws-amplify/backend, the type of Schema["Todo"] does not match the type of actual data item returned from await client.models.Todo.list(), Schema["TODO"] has a wrapping type prop.

So If I replace useState<Schema["Todo"][]>([]); with useState<Schema["Todo"]["type"][]>([]);, the build will success without error, I assume this is not by design but a bug.

hangoocn avatar May 02 '24 04:05 hangoocn

The quickstart vite-react app does not build succesfully due to type error of Schema["Todo"]; I am using 1.0.0 version of @aws-amplify/backend, the type of Schema["Todo"] does not match the type of actual data item returned from await client.models.Todo.list(), Schema["TODO"] has a wrapping type prop.

So If I replace useState<Schema["Todo"][]>([]); with useState<Schema["Todo"]["type"][]>([]);, the build will success without error, I assume this is not by design but a bug.

@hangoocn Yep , Just tried using 1.0.0 and that looks like a bug, We should be able to use below but that is not the case

useState<Schema["Todo"][]>([])

ujjwol05 avatar May 05 '24 02:05 ujjwol05

@ujjwol05 It seems the javascript quickstart doc is updated to use Array<Schema["Todo"]["type"]>

hangoocn avatar May 05 '24 19:05 hangoocn

Hey @ujjwol05, Please try as suggested above and If you are still experiencing the same problem and need further assistance, please leave a comment. This will enable us to reopen the issue and provide you with the necessary support.

AnilMaktala avatar May 20 '24 01:05 AnilMaktala

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.

github-actions[bot] avatar May 20 '24 01:05 github-actions[bot]