I have a page in which I generate in the back-end a table using the AG-GRID library, generating a file (js). This file once generated I call it from my front-end in which I use Handlebars. So far the code works correctly.
//BACKEND (I create a text string to generate the js file that creates the ag-grid table)
const list_membersJS = "var changePageSizeFunction; \n function setPivotTable() {\nconst columnDefs = [\n{ headerName: 'Nombre', field: 'nombre', filter: 'agTextColumnFilter'},\n{ headerName: 'Correo Electrónico', field: 'correo', cellRenderer: function (params) {var usuario = params.data.correo; return `<a target='_blank' href='mailto:${usuario}'>${usuario}</a>`;}},\n{ headerName: 'Empresa', field: 'empresa', filter: 'agSetColumnFilter'}];\nconst rowData = [" + txtrow + "];\nconst gridOptions = {\ncolumnDefs: columnDefs,\ndefaultColDef: {\nflex: 1,\nminWidth: 150,\nresizable: true,\nenableValue: true,\nenableRowGroup: true,\nsortable: true\n},\nanimateRows: true,\nrowData: rowData,\npagination: true,\npaginationPageSize: 15,\ndomLayout: 'autoHeight',\nenableSorting: true,\nenableFilter: true\n}\nconst eGridDiv = document.querySelector('#myGrid');\nnew agGrid.Grid(eGridDiv, gridOptions);\n agGrid.LicenseManager.setLicenseKey('[TRIAL]_this_AG_Grid_Enterprise_key_( AG-043903 )_is_granted_for_evaluation_only___Use_in_production_is_not_permitted___Please_report_misuse_to_( legal@ag-grid.com )___For_help_with_purchasing_a_production_key_please_contact_( info@ag-grid.com )___All_Front-End_JavaScript_developers_working_on_the_application_would_need_to_be_licensed___This_key_will_deactivate_on_( 30 September 2023 )____[v2]_MTY5NjAyODQwMDAwMA==4a43d539f6521489ef3e796e6a5d1d09'); \n changePageSizeFunction = function () {\n const pageSizeSelect = document.getElementById('pageSizeSelect');\n const selectedPageSize = parseInt(pageSizeSelect.value, 10);\n\n if (selectedPageSize === -1) {\n // Si se selecciona \"Todos\", establecer un tamaño de página alto para mostrar todos los elementos.\n gridOptions.api.paginationSetPageSize(Number.MAX_VALUE);\n } else {\n gridOptions.api.paginationSetPageSize(selectedPageSize);\n }\n}; \n }"
await fs.writeFileSync(__dirname + '/../public/js/list_members.js', dataFile)
//FRONTEND
<script src="../js/list_members.js"></script> --}}
The problem I have is that if two users perform an action or load the page at the same time, the file is displayed.js with the data of the last user since the file.js is a static file.
I would like to see how I can generate the ag-grid table from my backend and that from route I can pass a variable with my ag-grid table already configured, so that in handlebars I can call the variable and that when loading the table is displayed with the data of each user.
Similarly, if there is a faster way to solve this problem, it would be of great help.
ag-grid is a client-side library to add interactivity to data tables. Why not just send the data to your client as JSON using fetch
, then render the data on the client? This way, you will not have concurrency issues at all since every client will be in charge of rendering its own instance of the table.
How to fetch data from the client using fetch
: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
Here is the example from ag-grid's quickstart, modified to use fetch:
const columnDefs = [
{ field: "make" },
{ field: "model" },
{ field: "price" }
];
// Fetch the data, then setup the grid after the page has finished loading
document.addEventListener('DOMContentLoaded', () => {
// Querying the data using fetch and promises
fetch('/grid-data')
// Deserializing the data we received
.then(response => response.json())
// We have our data now, we initialize our table
.then(data => {
const gridDiv = document.querySelector('#myGrid');
new agGrid.Grid(gridDiv, {
columnDefs,
rowData: data,
});
})
});
Basically, your "inline" javascript would be moved from a dynamic file being written on disk by Node.js and you would load your script in the browser using a script
tag, just like you were.
What changes now is that you need to define a new endpoint in your Node server to serve this data as JSON.
const app = express()
// Other express config stuff
app.get('/grid-data', (req, res) => {
// This is our grid data. The properties of each object follows
// our column definitions. Whatever extra will not be shown.
const gridData = [
{
make: 'Honda',
model: 'Civic',
price: 9999.99
}
];
// Sending the data to the client as JSON
res.json(gridData);
})