Problem with getting data from Model

I am trying to use a Custom Component to plot a matrix with employees leave days. I have some transformers outputs with the data I need, already filtered and transformed for the month in consideration.

Here is the code of the Model:

{
  workers: {{Dipendenti_.value}},
  ferie: {{Ferie_mese_filter.value}}
}

which has the following preview:

{
  "workers": {
    "id": [
      "41",
      "1"
    ],
    "Nome": [
      "Luca",
      "Maria"
    ],
    "Cognome": [
      "Surname2",
      "Surname1"
    ]
  },
  "ferie": {
    "1": [
      16,
      17,
      18
    ]
  }
}

And here the Iframe code:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Worker Holiday Grid</title>
<style>
  body { font-family: Arial, sans-serif; margin: 0; padding: 0; }
  .grid { display: grid; grid-template-columns: 150px repeat(30, 1fr); border: 1px solid #ccc; }
  .header, .row { display: contents; }
  .surname-header { grid-column: span 31; } 
  .cell { border: 1px solid #ccc; text-align: center; padding: 5px; }
  .holiday { background-color: yellow; }
</style>
</head>
<body>

<div id="gridContainer"></div>

<script>
const workers = {
  "id": [
    "1",
    "42"
  ],
  "Nome": [
    "Vladislav",
    "Valentina"
  ],
  "Cognome": [
    "Surname1",
    "Surname2"
  ]
};

  
const ferie = {
  "1": [
    16,
    17,
    18
  ]
};


 /* 
const workers = model?.workers || {
  id: [],
  Nome: [],
  Cognome: []
};
*/
//const ferie = model?.ferie || {};

function buildGrid() {

  
  const workerSurnameMap = workers?.id?.reduce((acc, workerId, index) => {
    const cognome = workers?.Cognome[index];
    if (ferie[workerId]) {
      acc[workerId] = cognome;
    }
    return acc;
  }, {});

  const uniqueWorkerIds = Object.keys(workerSurnameMap);

  const gridContainer = document.getElementById('gridContainer');
  let grid = '<div class="grid">';

  // Header for surnames
  grid += '<div class="header surname-header"><div class="cell">Dipendente</div>';

  // Headers for days
  for (let i = 1; i <= 30; i++) {
    grid += `<div class="cell">${i}</div>`;
  }
  grid += '</div>'; 

  uniqueWorkerIds.forEach(workerId => {
    const cognome = workerSurnameMap[workerId]; 
    grid += '<div class="row">';
    grid += `<div class="cell">${cognome}</div>`; 
    
    for (let day = 1; day <= 30; day++) {
      let isHoliday = checkHoliday(workerId, day); 
      grid += `<div class="cell ${isHoliday ? 'holiday' : ''}"></div>`;
    }
    grid += '</div>'; 
  });

  grid += '</div>'; 
  gridContainer.innerHTML = grid;
}


function checkHoliday(workerId, day) {
  workerId = workerId.toString();
  day = parseInt(day, 10);

  if (ferie?.[workerId]?.includes(day)) {
    return true; 
  }
  return false; 
}

buildGrid();
</script>

</body>
</html>

If in the Iframe code I uncomment this part extracting the model variables:

 /* 
const workers = model?.workers || {
  id: [],
  Nome: [],
  Cognome: []
};
*/
//const ferie = model?.ferie || {};

it won't work. If I leave it commented and use some hard coded definitions of the variables, it works.
I have tried multiple ways to access the model data, but I can't.

What am I missing?

Attached you can see a working example when I hard code the variables.

Hey @vmalashevskyy,
Accessing the model is not as straight forward as assigning it, you should do it through window.Retool.subscribe.. refer to Custom Component Guide for how to exactly approach it.
In your case I guess you could do something like this:

let workers, ferie;
window.Retool.subscribe(function (model) {
  workers = model?.workers || {
    id: [],
    Nome: [],
    Cognome: []
  };
  ferie = model?.ferie || {};
});
// Then use them however you please in your custom component.

My advice would be to take a quick look at the guide and then have another go.

Hey,

thank you. Actually, in the other custom component I am using, I go through the window.Retool.subscribe, so I don't know why I overlooked it here.
I also put the buildGrid() inside the subscribe function, so that it updates the table.

Thanks for help.

1 Like