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!

4 Answers 4

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.

Sign up to request clarification or add additional context in comments.

1 Comment

it's called escape :)
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

Comments

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()
}

Comments

0

Try this.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.