BUG: List View hangs page on malformed data

Hi,

I was experimenting with list views and noticed that the list view is too sensitive about the data source being malformed. The entire page freezes and is only momentarily responsive, additionally, it is not easy to quickly revert.

Context:

  • Using Retool Cloud in Chrome browser
  • I'm listing questions and answers in nested list views. (see image)
  • As I'm experimenting, I define a temporary state ('test_data') to hold the JS object. (see image)
  • I assign row counts and the text components as per this 'test_data' object, as you would expect.

^See the images at the bottom. This works fine.

Reproduce error:

Remove a comma (',') after the first 'createdAt' and have a malformed js object as 'test_data'. As such:

[
  {
    "description": "This is the question 1",
    "createdAt": '2022-10-10 23:32'  // removed ',' here
    answers: ....

Result:

CPU goes up the roof. Memory went from 400 Mb to 2Gb.
It is difficult to change the text immediately, as clicks are not registered on the page, and keypresses are delayed or are also non-responsive.

Problem:

Some endless loop is probably triggered due to the malformed state being used with the list view. Furthermore, as you are writing the state, it is applied immediately, which means you will unavoidably have malformed JS at some point and get this error.

I'm not sure if I'm going about experimenting with listviews wrong before I transition to actual data. However, I'm sure it's not the intended behavior. It's also quite a convenient way to test components on fake data if it would have worked.

I have not tested malformed state variables with other components, this might not be related to list-views.

Best,
André


Hey @andreebie!

Thank you for surfacing this issue and providing the excellent repro app. I've passed it along to our dev team to take a look at and we can let you know here when there's a fix!

When you create a malformed JSON object Retool automatically switches to reading it as a string, instead of as an object. Since there are a lot of dynamic components being rendered in the nested listview on the basis of the value, I imagine there's a lot that changes if it suddenly stops being an object and starts being a string.

I think if you really wanted to, and as a temporary workaround, you might be able to edit the JSON in a JS query and then pass it to your temp state using state.setValue while you're testing.:

/* Edit me! */
const stateDefault = [
  {
    description: "This is the question 1",
    createdAt: "2022-10-10 23:32",
    answers: [
      {
        description: "This is the answer 1",
        createdAt: "2022-10-10 23:32",
      },
      { description: "This is the answer 2", createdAt: "2022-10-10 23:32" },
    ],
  },
  {
    description: "This is the question 2.",
    createdAt: "2022-10-10 23:32",
    answers: [
      { description: "This is the answer 21", createdAt: "2022-10-10 23:32" },
      { description: "This is the answer 22", createdAt: "2022-10-10 23:32" },
    ],
  },
];

state.setValue(stateDefault);

That way any JSON validation can happen in your JS query before the value is even passed to your state, you can check how it will render by running the query, and then once you have what you like you can copy it over.

Not sure how much that helps but hopefully it does a bit :slightly_smiling_face:

1 Like