aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.43k stars 2.13k forks source link

Possible unhandled promise rejection (): typeerror: object is not a function #11298

Closed elkee2003 closed 1 year ago

elkee2003 commented 1 year ago

Before opening, please confirm:

JavaScript Framework

React Native

Amplify APIs

DataStore

Amplify Categories

storage

Environment information

``` # Put output below this line System: OS: Windows 10 10.0.22000 CPU: (4) x64 Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz Memory: 506.38 MB / 7.88 GB Binaries: Node: 18.14.2 - C:\Program Files\nodejs\node.EXE npm: 9.5.1 - C:\Program Files\nodejs\npm.CMD Browsers: Edge: Spartan (44.22000.120.0), Chromium (112.0.1722.58) Internet Explorer: 11.0.22000.120 npmPackages: @azure/core-asynciterator-polyfill: ^1.0.2 => 1.0.2 @babel/core: ^7.20.0 => 7.21.3 @babel/preset-env: ^7.20.0 => 7.20.2 @babel/runtime: ^7.20.0 => 7.21.0 @react-native-async-storage/async-storage: ^1.18.1 => 1.18.1 @react-native-community/eslint-config: ^3.2.0 => 3.2.0 @react-native-community/geolocation: ^3.0.5 => 3.0.5 @react-native-community/netinfo: ^9.3.7 => 9.3.7 @react-native-masked-view/masked-view: ^0.2.8 => 0.2.8 @react-native-picker/picker: ^2.4.9 => 2.4.9 @react-navigation/drawer: ^6.6.2 => 6.6.2 @react-navigation/native: ^6.1.6 => 6.1.6 @react-navigation/stack: ^6.3.16 => 6.3.16 @tsconfig/react-native: ^2.0.2 => 2.0.3 @types/jest: ^29.2.1 => 29.5.0 @types/react: ^18.0.24 => 18.0.28 @types/react-test-renderer: ^18.0.0 => 18.0.0 HelloWorld: 0.0.1 amazon-cognito-identity-js: ^6.2.0 => 6.2.0 aws-amplify: ^5.0.22 => 5.0.22 aws-amplify-react-native: ^7.0.2 => 7.0.2 babel-jest: ^29.2.1 => 29.5.0 eslint: ^8.19.0 => 8.36.0 jest: ^29.2.1 => 29.5.0 metro-react-native-babel-preset: 0.73.8 => 0.73.8 prettier: ^2.4.1 => 2.8.6 react: 18.2.0 => 18.2.0 react-native: 0.71.4 => 0.71.4 react-native-gesture-handler: ^2.9.0 => 2.9.0 react-native-google-places-autocomplete: ^2.5.1 => 2.5.1 react-native-maps: ^1.4.0 => 1.4.0 react-native-maps-directions: ^1.9.0 => 1.9.0 react-native-reanimated: ^3.0.2 => 3.0.2 react-native-safe-area-context: ^4.5.0 => 4.5.0 react-native-screens: ^3.20.0 => 3.20.0 react-native-vector-icons: ^9.2.0 => 9.2.0 react-test-renderer: 18.2.0 => 18.2.0 typescript: 4.8.4 => 4.8.4 npmGlobalPackages: @aws-amplify/cli: 11.0.3 expo-cli: 6.3.2 npm: 9.5.1 ```

Describe the bug

I try fetching my data from DataStore to query it but it keeps giving me this error: P Screenshot (5) Possible unhandled promise rejection (): typeerror: object is not a function.

Expected behavior

It is meant to successfully query my data, because I went back to check in the models and User is an object

Reproduction steps

  1. I import DataStore from aws-amplify
  2. I access my User object in my models
  3. I use useEffect to try to query the sub (which is a field in the User) of User
  4. I save
  5. I get the error

Code Snippet

// Put your code below this line.

import { createContext, useState,useEffect, useContext } from "react"; import {Auth, DataStore} from 'aws-amplify'; import { User } from "../models";

const AuthContext = createContext({})

const AuthContextProvider = ({children})=>{ const [authUser, setAuthUser] = useState(null) const [dbUser, setDbUser] = useState(null) const sub = authUser?.attributes?.sub;

useEffect(()=>{
    Auth.currentAuthenticatedUser({bypassCache: true}).then(setAuthUser)
},[]);

useEffect(()=>{
    DataStore.query(User, (user)=>user.sub("eq", sub)).then((users)=>setDbUser(users[0]))
}, [sub])

return(
    <AuthContext.Provider value={{authUser, dbUser, sub, setDbUser }}>
        {children}
    </AuthContext.Provider>
)

}

export default AuthContextProvider;

export const useAuthContext = ()=> useContext(AuthContext)

Log output

``` // Put your logs below this line ```

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

Tecno Camon 19

Mobile Operating System

Android 12

Mobile Browser

Chrome

Mobile Browser Version

No response

Additional information and screenshots

No response

elkee2003 commented 1 year ago

So apparently there is something new called 'Lazy loading & nested query predicates for AWS Amplify DataStore'. It is the change of the syntax from: Before: DataStore.query(Post, p => p.id(‘eq’, ‘123’)) Now: DataStore.query(Post, p => p.id.eq(‘123’))

So, in my case, it is: useEffect(()=>{ DataStore.query(User, (user)=>user.sub.eq(sub)).then((users)=>setDbUser(users[0])) }, [sub])

chrisbonifacio commented 1 year ago

Hi @elkee2003 👋 yes, the DataStore predicate syntax has changed between v4 and v5 of the JS library. Has this resolved the issue for you?

elkee2003 commented 1 year ago

Hi @elkee2003 👋 yes, the DataStore predicate syntax has changed between v4 and v5 of the JS library. Has this resolved the issue for you?

Yes that problem has been solved. However, I am trying to update a user and it is giving me an error. I believe the error is coming from the syntax. Could you please help me pin point it out? I have uploaded the error message and the code photos Screenshot (7) Screenshot (8)

`const ProfileScreen = () => {

const {sub, dbUser, setDbUser} = useAuthContext()

const [name, setName] = useState(dbUser?.name || "")
const [address, setAddress] = useState(dbUser?.address || "")
const [lat, setLat] = useState(dbUser?.lat + "" || "0")
const [lng, setLng] = useState (dbUser?.lng + "" || "0")    

const onSave = async ()=>{
  if (dbUser){
    await updateUser()
  }else{
    await createUser()
  }

  // Update User function
  const updateUser = async ()=>{
    const user = await DataStore.save(
      User.copyOf(dbUser, (updated)=>{
        updated.name = name;
        updated.address = address;
        updated.lat = parseFloat(lat);
        updated.lng = parseFloat(lng);
      })
    );
    setDbUser(user)
  };

  // Create User function
  const createUser = async () =>{
    try{
      const user = await DataStore.save(new User({
        name, 
        address,
        lat:parseFloat(lat), 
        lng:parseFloat(lng), sub
      }))
      console.log(user)
      setDbUser(user)
    }catch(e){
      Alert.alert("Error", e.message)
    }
  };

}`
chrisbonifacio commented 1 year ago

@elkee2003 awesome, glad you were able to resolve the issue!

This new error doesn't sound like it's coming from DataStore. "undefined is not a function", to me, sounds like an undefined function is attempting to be called. It might be the way updateUser and createUser are being called before they are defined below.

I would try either changing them to normal functions rather than arrow functions so they are hoisted or simply move the if statement below the function declarations.

example:

const onSave = async ()=>{
  if (dbUser){
    await updateUser()
  }else{
    await createUser()
  }

  // Update User function
  async function updateUser() {
    const user = await DataStore.save(
      User.copyOf(dbUser, (updated)=>{
        updated.name = name;
        updated.address = address;
        updated.lat = parseFloat(lat);
        updated.lng = parseFloat(lng);
      })
    );
    setDbUser(user)
  };

  // Create User function
  async function createUser() {
    try{
      const user = await DataStore.save(new User({
        name, 
        address,
        lat:parseFloat(lat), 
        lng:parseFloat(lng), sub
      }))
      console.log(user)
      setDbUser(user)
    }catch(e){
      Alert.alert("Error", e.message)
    }
  };

}`
Abdullah47744 commented 1 year ago

hello i face the same issue and am unable to solve same like above 1st one is in useeffect and 2nd in update user i follow your suggestion but unable to solve

Abdullah47744 commented 1 year ago

async function updateUser() { const user = await DataStore.save( User.copyOf(dbUser , (updated) => { updated.name = name; updated.address = address; updated.lat = parseFloat(lat); updated.lng = parseFloat(lng); }) ); setdbUser(user); };

Abdullah47744 commented 1 year ago

DataStore.query(User, (user) => user.sub.eq(sub)).then(setdbUser) }, [sub])

Abdullah47744 commented 1 year ago

ERROR [ERROR] 41:09.978 DataStore - The source object is not a valid model {"source": []} WARN Possible Unhandled Promise Rejection (id: 1): Error: The source object is not a valid model Error: The source object is not a valid model