Grid View and List View not propagating data correctly on update

I have an application which has several different tabs with several grid views within each. I have an issue where for some reason, when the data updates for each grid view the grid view wont update (fill up from empty, or update to new data).

To give an example of this occurring:

Here is one such grid which has not rendered even though the data is present, sometimes it renders, sometimes it does not. It's completely random from what I can tell.

You can see here when I mouse over the data source it has the data and it is correct.

You can also see the data in the explore JSON component below which has the same source.

Removing and reapplying exactly the same data source makes it render immediately as expected, but this obviously doesn't work for my end users.

I originally had all of this happening through a transformer for each tab, but since it was doing this I have rewritten the whole thing as a JS Query to see if it would resolve the issue. It has not.

I do not believe the grid is updating correctly when the values change as when I look at the component inside the grid (see image)...


The {{item}} and {{i}} variables are undefined even thought the grid component data is filled as you can see from the higher up screenshots.

Any solutions?

This is the first time we finally decided to actually build something big in Retool and we've come across two pretty significant bugs, this one being completely showstopping and the other being pretty annoying and likely to increase the chances of human error in a regulated activity: Key Value order incorrect - #13 by Mentioum

:pray:

Also hi @dvdhsu long time since S17 Jeremy Hindle here.

Hi @Mentioum, thanks for using our new Grid component -- I hadn't seen this bug before but I'm looking into it now.

You mentioned that your datasource is a JS query and used to be a transformer, can you share a bit more about where you're getting the data and what your JS query looks like?

Hi @AnnaW

I have a resource query which get the insurance application.
I have a js query which manipulates the data which comes back from the above resource query.

Heres the resource query.


That gets triggered on a tabbed container change event with the following code:

  case "view_application":
    ApplicationBrowser.setCurrentView('basic');
    await GetApplicationByID.trigger({
      additionalScope: {
        "id": selected_application_id.value
      }
    });
    await ApplicationParsing.trigger();
    return;

The below query then runs after the first finishes (see code above).

//ApplicationParsing
const data = GetApplicationByID.data;
const snapshot = data.snapshot;

const application_data = {
  "named_drivers": [],
  "motoring_convictions": [],
  "convictions": [],
  "claims": [],
  "disabilities": [],
  "cars": []
}

//For each of the named drivers in the application look them up in the Customer object and populate an array.
const named_driver_ids = snapshot.named_drivers.map(nd => nd.driver_id);

//Iterate of all of a customers named_drivers and put them into an array when they are associated with the application.
const named_drivers = _.filter(snapshot.customer.named_drivers, function(nd) {
  return named_driver_ids.includes(nd.uid);
})

//Aggregate all of the Applications motoring convictions
var customer_motoring_convictions = snapshot.customer.motoring_convictions || []; //Get all motoring convictions by the customer
var named_driver_motoring_convictions = [];
named_drivers.forEach((driver) => {
  if (driver.motoring_convictions) {
    named_driver_motoring_convictions.push(...driver.motoring_convictions);
  }
})
var motoring_convictions = customer_motoring_convictions.concat(named_driver_motoring_convictions);


//Aggregate all convictions
var customer_convictions = snapshot.customer.convictions || [];
var named_driver_convictions = [];
named_drivers.forEach((driver) => {
  named_driver_convictions.push(...driver.convictions)
})
var convictions = customer_convictions.concat(named_driver_convictions);


//Aggregate all claims
var customer_claims = snapshot.customer.claims || [];
var named_driver_claims = [];
named_drivers.forEach((driver) => {
  named_driver_claims.push(...driver.claims);
})
var claims = customer_claims.concat(named_driver_claims) || [];

//Aggregate all disabilities
var customer_disabilities = snapshot.customer.disabilities || [];
var named_driver_disabilities = [];
named_drivers.forEach((driver) => {
  named_driver_disabilities.push(...driver.disabilities);
})
var disabilities = customer_disabilities.concat(named_driver_disabilities);

//Aggregate cars which are applicable to insurance process
//Get and enrich Custodian cars
const custodian_cars = snapshot.custodian_cars || [];
const external_cars = snapshot.everyday_vehicles || [];
const customer_cars = snapshot.customer.custodian_cars || [];
const external_customer_cars = snapshot.customer.external_vehicles || [];

//Enrich the above with customer data
const enriched_custodian_cars = [];
custodian_cars.forEach((application_car) =>{
  let car_id = application_car.vehicle_id;
  customer_cars.forEach((customer_custodian_car) => {
    if (customer_custodian_car.uid == car_id) {
      enriched_custodian_cars.push(customer_custodian_car);
    }
  });
});

const enriched_external_vehicles = [];
external_cars.forEach((external_car) => {
  let car_id = external_car.external_vehicle_id;
  external_customer_cars.forEach((customer_exteral_car) => {
    if(customer_exteral_car.uid == car_id) {
      enriched_external_vehicles.push(customer_exteral_car);
    }
  });
})

const cars = enriched_custodian_cars.concat(enriched_external_vehicles);

application_data.named_drivers = named_drivers || [];
application_data.motoring_convictions = motoring_convictions || [];
application_data.convictions = convictions || []
application_data.claims = claims || [];
application_data.disabilities = disabilities || [];
application_data.cars = cars || [];
application_data.snapshot = snapshot;

return application_data;

The data is 100% working correctly as the debug fields (the JSON explore) on every page are always showing the full correct data, as is the Grid component input field. It just doesn't propagate into the grid.

Hopefully that helps.

Thanks for the info @Mentioum! I was able to reproduce this and am aiming to have the fix out later today.

I believe this may be connected to when list views or grid views only have one "row" -- if you're able to use a 1-column list so that the component is displaying more than one row, that should be a temporary workaround.

I did try that, and it still happened from memory. I'll try again though, and looking forward to a fix, kinda blocked on this :slight_smile:

Actually thinking about it the reason that didn't fix it for me sometimes might be because my array is only one item long sometimes, so the issue (if its to do with 1 row) will continue to happen anyway even if I make it a single column grid / list.

I added several empty objects to the end of every array and they seem to be rendering consistently now. Looks like you know the issue, fingers crossed on a quick fix :pray:

Thanks for validating! The fix should be out now with version 3.26 so let me know if you're still encountering it.

1 Like

Hi @AnnaW when will that version be available to cloud customers?

3.26 should have been released yesterday! Hope this helps.

2 Likes