Amplify-js: DataStore doesn't work with nullable lists in schema (bug)

Created on 2 Apr 2020  路  6Comments  路  Source: aws-amplify/amplify-js

Describe the bug

DataStore doesn't work with nullable lists in schema, and causes the app to throw the following error upon syncing:

Error: Field checklistItems should be of type string[], object received. null

Amplify CLI Version

4.17.2

To Reproduce

I created a React Native app in which I use DataStore. My schema looks like this:

type UserContent 
  @model
  @auth(rules: [{ allow: private }])
{
  id: ID!
  testField: String
  checklistItems: [String!]
}

After the user logs in, the app navigates to the home screen, on which the DataStore starts observing the UserContent model:

useEffect(() => {
    const subscription = DataStore.observe(UserContent).subscribe(msg => {
        console.log(msg);
    });

    return () => subscription.unsubscribe();
}, []);

I successfully execute the following mutation from the AppSync Queries page to add new UserContent:

mutation createUserContent {
  createUserContent(input: {}) {
    id
    testField
    checklistItems
    _version
    _lastChangedAt
    _deleted
  }
}

The mutation returns the following response:

{
  "data": {
    "createUserContent": {
      "id": "62675d48-c748-4560-8c84-c09e2debccc3",
      "testField": null,
      "checklistItems": null,
      "_version": 1,
      "_lastChangedAt": 1585856427738,
      "_deleted": null
    }
  }
}

After the mutation executes successfully, the new data syncs to my app, after which the app throws the following error:

Error: Field checklistItems should be of type string[], object received. null

Object.entries.forEach$argument_0
    datastore.js:220:30
forEach
    [native code]:0
initializeInstance
    datastore.js:208:4
produce$argument_1
    datastore.js:239:34
i.produce
    immer.esm.js:1:14843
<unknown>
    [native code]:0
Model
    datastore.js:238:27
modelInstanceCreator
    datastore.js:205:11
dataSubsObservable.subscribe$argument_0
    index.js:186:64
notifySubscription
    Observable.js:135:15
onNotify
    Observable.js:179:20
next
    Observable.js:235:14
buffer.forEach$argument_0
    subscription.js:341:57
forEach
    [native code]:0
SubscriptionProcessor.prototype.drainBuffer
    subscription.js:341:12
queryObservable.map.subscribe$argument_0.next
    subscription.js:284:60
notifySubscription
    Observable.js:135:15
onNotify
    Observable.js:179:20
next
    Observable.js:235:14
_this2.subscribe$argument_0.next
    Observable.js:327:12
notifySubscription
    Observable.js:135:15
onNotify
    Observable.js:179:20
next
    Observable.js:235:14
observable.subscribe$argument_0.next
    PubSub.js:169:52
notifySubscription
    Observable.js:135:15
onNotify
    Observable.js:179:20
next
    Observable.js:235:14
prototype._handleIncomingSubscriptionMessage
    AWSAppSyncRealTimeProvider.js:448:16
<unknown>
    [native code]:0
EventTarget.prototype.dispatchEvent
    event-target-shim.js:818:20
_eventEmitter.addListener$argument_1
    WebSocket.js:232:8
emit
    EventEmitter.js:189:10
__callFunction
    MessageQueue.js:425:19
__guard$argument_0
    MessageQueue.js:112:6
__guard
    MessageQueue.js:373:10
callFunctionReturnFlushedQueue
    MessageQueue.js:111:4
callFunctionReturnFlushedQueue
    [native code]:0

According to the GraphQL documentation, the way I have setup my schema should allow for nullable list.

Executing the following mutation doesn't throw an error in the app:

mutation createUserContent {
  createUserContent(input: {
    checklistItems: ["test"]
  }) {
    id
    testField
    checklistItems
    _version
    _lastChangedAt
    _deleted
  }
}

So it seems like I can't have lists that are null? I've tried the following variations, but I encountered the same problem:

checklistItems: [String!]
checklistItems: [String]

For this last variation I supplied an empty list (which is valid according to the GraphQL docs), but it still prevented me from creating a UserContent record:

checklistItems: [String]!

Error:

{
  "data": {
    "createUserContent": null
  },
  "errors": [
    {
      "path": [
        "createUserContent"
      ],
      "data": null,
      "errorType": "DynamoDB:DynamoDbException",
      "errorInfo": null,
      "locations": [
        {
          "line": 15,
          "column": 3,
          "sourceName": null
        }
      ],
      "message": "Supplied AttributeValue is empty, must contain exactly one of the supported datatypes (Service: DynamoDb, Status Code: 400, Request ID: H5RC1PLLALQ3HJ4EAN8F1TQLRBVV4KQNSO5AEMVJF66Q9ASUAAJG)"
    }
  ]
}

Expected behavior

I expect to be able to define a nullable list on my schema, or at least allow for an empty list, and still successfully sync on my app.

Desktop:

  • OS: macOS Catalina
  • Node Version: v13.5.0
DataStore React Native

Most helpful comment

@mdoesburg I'm going to look into reproducing this issue today.

All 6 comments

Transferring this to the JS repo. cc @sammartinez

@sammartinez Could your team have a look at this bug please?

@mdoesburg I'm going to look into reproducing this issue today.

@Ashish-Nanda Thank you!

@Ashish-Nanda Hi, I was wondering if you got a chance to reproduce this yet? Let me know if you need any more details from my end.

Hi @mdoesburg, we are currently looking into this issue. It is being tracked here: https://github.com/aws-amplify/amplify-js/issues/5040
Closing this issue as a duplicate.

Was this page helpful?
0 / 5 - 0 ratings