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.44k stars 2.13k forks source link

Datastore Not saving additional rows after subsequent save attempts #9970

Closed gmineropfdrive closed 2 years ago

gmineropfdrive commented 2 years ago

Before opening, please confirm:

JavaScript Framework

React

Amplify APIs

DataStore

Amplify Categories

storage, api

Environment information

``` # Put output below this line System: OS: Windows 10 10.0.19044 CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz Memory: 17.23 GB / 31.70 GB Binaries: Node: 16.13.1 - C:\Program Files\nodejs\node.EXE Yarn: 1.22.11 - ~\AppData\Roaming\npm\node_modules\yarn\bin\yarn.CMD npm: 8.3.0 - C:\Program Files\nodejs\npm.CMD Browsers: Edge: Spartan (44.19041.1266.0), Chromium (102.0.1245.33) Internet Explorer: 11.0.19041.1566 npmPackages: @auth0/auth0-react: ^1.8.0 => 1.9.0 @aws-amplify/datastore: ^3.5.0 => 3.7.4 @aws-amplify/ui-react: ^1.2.21 => 1.2.26 @testing-library/jest-dom: ^5.11.4 => 5.16.1 @testing-library/react: ^11.1.0 => 11.2.7 @testing-library/user-event: ^12.1.10 => 12.8.3 autoprefixer: ^10.4.1 => 10.4.2 aws-amplify: ^4.3.3 => 4.3.12 framework7-icons: ^5.0.5 => 5.0.5 framework7-icons-react: undefined () framework7-icons-svelte: undefined () framework7-icons-vue: undefined () konsta: ^0.7.0 => 0.7.0 konsta/react: undefined () konsta/vue: undefined () moment: ^2.29.1 => 2.29.1 postcss: ^8.4.5 => 8.4.5 (7.0.39) react: ^17.0.2 => 17.0.2 react-checkbox-tree: ^1.7.2 => 1.7.2 react-dom: ^17.0.2 => 17.0.2 react-icons: ^4.3.1 => 4.3.1 react-infinite-scroll-component: ^6.1.0 => 6.1.0 react-rangeslider: ^2.2.0 => 2.2.0 react-router-dom: ^6.2.1 => 6.2.1 react-scripts: ^5.0.0 => 5.0.0 react-super-responsive-table: ^5.2.0 => 5.2.0 recoil: ^0.5.2 => 0.5.2 recoil-persist: ^4.0.0 => 4.0.0 tailwindcss: ^3.0.9 => 3.0.15 web-vitals: ^0.2.4 => 0.2.4 workbox-background-sync: ^5.1.3 => 5.1.4 (6.4.2) workbox-broadcast-update: ^5.1.3 => 5.1.4 (6.4.2) workbox-cacheable-response: ^5.1.3 => 5.1.4 (6.4.2) workbox-core: ^5.1.3 => 5.1.4 (6.4.2) workbox-expiration: ^5.1.3 => 5.1.4 (6.4.2) workbox-google-analytics: ^5.1.3 => 5.1.4 (6.4.2) workbox-navigation-preload: ^5.1.3 => 5.1.4 (6.4.2) workbox-precaching: ^5.1.3 => 5.1.4 (6.4.2) workbox-range-requests: ^5.1.3 => 5.1.4 (6.4.2) workbox-routing: ^5.1.3 => 5.1.4 (6.4.2) workbox-strategies: ^5.1.3 => 5.1.4 (6.4.2) workbox-streams: ^5.1.3 => 5.1.4 (6.4.2) npmGlobalPackages: @aws-amplify/cli: 6.1.0 @salesforce/cli: 1.3.0 aws-cdk: 2.1.0 marked: 2.0.1 npm: 8.3.0 sfdx-cli: 7.94.3 typescript: 4.1.3 yarn: 1.22.11 ```

Describe the bug

we are using Datastore to save a custom graphql model as documented, and everything works fine on the first iteration or attempt of doing so, however, when we attempt to save/update new rows, we get an error stating that a field is missing, however, this is not the case.

Expected behavior

Datastore.Save should create a new instance of the model and save a new row, as documented.

Reproduction steps

create a schema which has the following:

type User@model @auth(rules: [{allow: public}]) {
  id: ID!
  username : String! @primaryKey
  organizationId: String!
  org: Org! @hasOne(fields: ["organizationId"])
  name: String
}

type Org @model @auth(rules: [{ allow: public }]) {
  id: ID!
  organizationId: String! @primaryKey
}

(we have a list of users, which are linked to an organization Id returned from an API)

using Datastore, we try to save multiple users belonging to an org as follows:

const saveUsers = async (selectedUsers, saveOrg) =>{
        for (const user of selectedUsers) {
          let storedUser = null;
          if (user.stored) {
              storedUser = userTable.model.copyOf(user.stored, updated => {
                  updated.username = user.Username;
                  updated.organizationId= orgId;
                  updated.org = saveOrg;
                  updated.name = user.Name;
               });
          } 
        else {
         storedUser = new userTable.model({
                            username : user.Username,
                            organiztionId: orgId,
                            org: saveOrg,
                            name: user.Name
                        });
}
 const savedUser = await DataStore.save(storedUser);
}

All users save fine the first time that we (for example, select what users to save through an interface), however, if we re-open the interface and add new users, we get the error

datastore.ts:273 Uncaught (in promise) Error: Field organizationId is required, however, after debugging, we validate the the organizationId IS there.

additionally, for some strange reason, if I change the instance of the user model when saving as follows:

storedUser = new userTable.model({
                            username : user.Username,
                            organizationID: orgId,
                            org: saveOrg,
                            name: user.Name
                        });

it will save on the device locally, but the organizationID will be null....

fyi: the schema is set to public for testing purposes.

Code Snippet

// Put your code below this line.
const saveUsers = async (selectedUsers, saveOrg) =>{
        for (const user of selectedUsers) {
          let storedUser = null;
          if (user.stored) {
              storedUser = userTable.model.copyOf(user.stored, updated => {
                  updated.username = user.Username;
                  updated.organizationId= orgId;
                  updated.org = saveOrg;
                  updated.name = user.Name;
               });
          } 
        else {
         storedUser = new userTable.model({
                            username : user.Username,
                            organiztionId: orgId,
                            org: saveOrg,
                            name: user.Name
                        });
}
 const savedUser = await DataStore.save(storedUser);
}

Log output

``` // Put your logs below this line datastore.ts:273 Uncaught (in promise) Error: Field organizationId is required ```

aws-exports.js

const awsmobile = {
    "aws_project_region": "us-east-2",
    "aws_appsync_graphqlEndpoint": "https://xirrcxi3f5b3zpjgni5omi43sm.appsync-api.us-east-2.amazonaws.com/graphql",
    "aws_appsync_region": "us-east-2",
    "aws_appsync_authenticationType": "API_KEY",
    "aws_appsync_apiKey": "da2-yhpmkkccqrarpc4ezr6unc3geq",
    "aws_cloud_logic_custom": [
        {
            "name": "fsmInitialOrgSetup",
            "endpoint": "https://cmnunplnz1.execute-api.us-east-2.amazonaws.com/gosyncto",
            "region": "us-east-2"
        }
    ]
};

Manual configuration

No response

Additional configuration

No response

Mobile Device

not applicable

Mobile Operating System

not applicable

Mobile Browser

Brave

Mobile Browser Version

Version 1.39.111 Chromium: 102.0.5005.61 (Official Build) (32-bit)

Additional information and screenshots

No response

dpilch commented 2 years ago

I see a typo that may lead to this issue. In the provided code snippet, under the else block, you have used organiztionId (missing "a"). Could you try fixing this and see if the issue persists?

chrisbonifacio commented 2 years ago

Hi 👋 Closing this as we have not heard back from you. If you are still experiencing this issue and in need of assistance, please feel free to comment and provide us with any information previously requested by our team members so we can re-open this issue and be better able to assist you.

Thank you!