How to send JSON array through graphQL and AWS AppSync to add data to Dynamo Table?
Asked Answered
S

4

7

What I'm trying to do is to send data from a React Native app through AppSync so that I can update a user's data on a dynamo table. I can perform all of my CRUD operations, just not a list of data. When I try, I get an error that what I'm sending isn't a valid JSON. However, my input passes as valid JSON when I put it through a JSON linter.

To try and solve this problem, I've changed my input flow to the simplest possible process. Originally I was pulling my JSON from a parsed JSON string that was locally cached. I thought that perhaps there was an issue with the JSON.parse(obj) function. That didn't hold up to reason. So I moved all of my input out of a JS object and into a JSON that isn't stored in a variable beforehand but is directly passed to the API I'm using (https://aws-amplify.github.io/docs/js/api).

After this didn't work, I thought that maybe my GraphQL Schema was wrong for the object type I was sending, but didn't find anything amiss.

My schema in AppSync using GraphQL is defined as follow:

input CreateUserInput {
  email: String!
  data: AWSJSON
}

The request I'm sending is as follows:

const dbReturn = await API.graphql(graphqlOperation(
  mutations.createUser, {
    input: {
      "email": "[email protected]",
      "data": [{
        "num": 34,
      }]
    }
  }
));

The error message says:

"Variable 'data' has an invalid value. Unable to parse [{num=34}] as valid JSON."

What confuses me is that "[{num=34}]" isn't the input I'm giving it. I'm sending it "[{"num": 34}]" which is valid JSON. I would expect it to be able to parse my input and send the data to my dynamo table seeing as the JSON input is valid.

Anybody have any ideas what I can do to get past this? Thank you for the help!

Stilliform answered 25/7, 2019 at 14:52 Comment(0)
S
21

Figured it out. The answer lies in the GraphQL schema.

"createUser": {
    "email": "Hello, world!",
    "data": "{\"key\":\"value\"}",
}

The input for a "complex data type" is just a string. So when making the request, you just have to pass in the data as something something like JSON.stringify(variable.data). I hope this helps someone along the way.

Stilliform answered 25/7, 2019 at 17:34 Comment(1)
it's called escape :)Yorgo
Y
5

In this image, the sources are AWSJSON type which can hold object or array, if you want to use mutations since it's a JSON object you will need to do escape in order to create the item in the app sync. enter image description here

enter image description here

Yorgo answered 12/11, 2020 at 14:7 Comment(0)
C
4

I had the opposite issue. I am not using code to create the query but using gql directly. If I use String in input then I get a stringified JSON in my db which is not what I want. Instead I had to ensure there were no quotes around - in your case, num.

Schema

Item {
 data: AWSJSON
}
ItemInput {
  data: AWSJSON
}

Query

mutation {
 createUser {
   data: { num: 34 } // Not { "num": 34 }
 }
}

This ensures my data is not stored as a string and that on query I get parseable JSON back instead of a quote escaped string.

My VTL templates do do anything unusual on mutations but on query I do return as:

{
  "data" :  $util.toJson($ctx.result.get('data')) // OR $ctx.result.get('data').toJSON()
}
Cantone answered 13/11, 2019 at 14:53 Comment(0)
B
0

Try this.

const dbReturn = await API.graphql(graphqlOperation(
  mutations.createUser, {
    input: {
      "email": "[email protected]",
      "data":JSON.stringify([{
        "num": 34,
      }])
    }
  }
));
Balmuth answered 15/12, 2022 at 10:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.