Request body works when hardcoded, fails when passed as variable

I have an editable table and want to save the changes to the backend of my application. To do so, I use three elements:

  • The table's changesetArray
  • An OpenAPI resource (with a POST endpoint that takes an array of changes as a request body)
  • A transformer that maps the rows from the changeset to the format the API call needs.

The problem?

When I hardcode the transformer's value in the request body, it works. When I use the transformer's value as a variable in the request body, it fails with this error message:

Unexpected token { in JSON at position 1

This is the code in the transformer:

let changeset = {{ parkingTable.changesetArray }};

let changesetArray = Object.entries(changeset);

changesetArray = changesetArray.map(
  ([key, row]) => ({
    carOwnerId: row.id.toString(),
    parkingSpotId: row.parkingSpotId.toString()
  })
)

return changesetArray;

It just renames two fields from the changeset entries and feeds them to the API call:

Screenshot 2025-02-13 at 12.11.42

However, if I just copy the result of the transformer and paste it in the request body, it works, which makes no sense:

Screenshot 2025-02-13 at 12.12.48

I don't understand why the same value fails when passed as a variable, and works when hardcoded.

Can you help me out?

Hey there @Javi_V,

Could it be that your API expects a string, but the variable is being read as an object. You can try {{ JSON.stringify (formattedChangeSet.value) }}

Nope, same problem:

Unexpected token { in JSON at position 1

Ironically, when I hardcode the exact same value that the transformer produces, it works:

[{"carOwnerId":"3","parkingSpotId":"7"},{"carOwnerId":"2","parkingSpotId":"5"}]

As you can see here, I'm passing an array, and it works. And it's literally the same output that the transformer produces.

As an extra hint, I took a look at the network tab on my browser, and copied the body of the requests (hardcoded and variable reference) and I see that it's different:

hardcoded (correct):

"requestBodyParams": {
      "0": [
        {
          "carOwnerId": "3",
          "parkingSpotId": "7"
        },
        {
          "carOwnerId": "2",
          "parkingSpotId": "5"
        }
      ],
      "length": 1
    },

Transformer result reference:

"requestBodyParams": {
  "length": 0
},

Do these details offer any context?

How strange...

Could you take a look at your API's status by clicking on "View State" when right clicking on it and see what the query is evaluating to?

Yes, this is the query's state after calling it with the transformer's value:

and this is the query after calling it with the hardcoded value:
[{"carOwnerId":"7","parkingSpotId":"4"},{"carOwnerId":"11","parkingSpotId":"3"}]

This is indeed strange. I read a similar issue here, albeit with a different API, but there wasn't a solution, rather a hacky workaround.

I'll let other members of the forum, or the retool team to chip into this one. Sorry I was not able to help!

@Javi_V ,

Yes, this must be frustrating if your transformer produces the same exact result as the hardcoded data. Can you try it with a regular javascript query instead of a transformer?

Also, would you mind exporting your json to me so I can take a look at your data? Please also provide the api resource. Thanks!

@Javi_V,
Just checking in to see if your issue has been resolved.

I just want to share that I notice the same problem too on my local retool.
while troubleshooting I can confirm from my logs that when this problem occurs it is not hitting my API at all.
I suspect it is not treating {{ as a reference to a variable and just tries to parse it like it is the raw input thus complaining about the unexpected { at 1 . so retool just stops and not make the request
I'm still trying to figure out why, but currently clueless.

for extra info, for my case I tried getting the value from a variable or a javascript query data.
i didn't use a transformer

I found more clues as I work on it further. so I'm calling an OpenAPI that is expecting an array of objects on the request body.

[
    {
      "attribute": "location",
      "values": [
        "New York",
        "Los Angeles"
      ]
    }
]

when I changed the API to expect instead a field that wraps the array so it is like

{
  "filters": [
    {
      "attribute": "location",
      "values": [
        "New York",
        "Los Angeles"
      ]
    }
  ]
}

That made the request body input from retool different and not complained with the reference value anymore and was able to run the API query properly.