Non-reactive operations within reactive chain of operations #1507
-
I'm trying to create a dashboard with a relatively large datasets with many rows, that requires some complex filtering. On my naively created dashboard, every time I make any small changes in the filters, the page reacts to every change, then it stalls with filtering a large array for a couple of seconds. Is there any way if I want to make filtering work only when I click 'apply filter' button, instead of everything reactive? In short, I'd like to break a reactive chain somewhere in the middle. const data = [
{ id: 1, value: 1},
{ id: 2, value: 2},
{ id: 3, value: 3},
{ id: 4, value: 4},
{ id: 5, value: 5}
];
// selecting values here will update the following value display and the table
const selectedData = view(Inputs.select(data.map(d => d.id), { multiple: true }));
/* html
${Array.from(selectedData)}
*/
const tableData = data.filter(d => selectedData.indexOf(d.id) > -1);
display(Inputs.table(tableData)); But I'd like to make like it like (won't work): const data = [
{ id: 1, value: 1},
{ id: 2, value: 2},
{ id: 3, value: 3},
{ id: 4, value: 4},
{ id: 5, value: 5}
];
// selecting values here should update the following value display,
// while I don't want the following table to wait for button click
const selectedData = view(Inputs.select(data.map(d => d.id), { multiple: true }));
/* html
${Array.from(selectedData)}
<button id="apply-filter">APPLY FILTER</button>
*/
// this works if selectedData is not reactive
// but if selectedData is reactive, then it 'clicks' every time when selectedData is updated.
const filterBtn = document.getElementById('apply-filter');
const tableData = Generators.observe(notify => {
const clicked = () => notify(data.filter(d => Array.from(selectedData).indexOf(d.id) > -1));
clicked();
filterBtn.addEventListener("click", clicked);
return () => filterBtn.removeEventListener("click", clicked);
});
display(Inputs.table(tableData)); |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Resolved. Basically, removing the call to const data = [
{ id: 1, category: 1 },
{ id: 2, category: 1 },
{ id: 3, category: 1 },
{ id: 4, category: 2 },
{ id: 5, category: 2 }
];
const selectedCategory = view(Inputs.select(data.map(d => d.category), { unique: true })) const selectedData = view(Inputs.table(data.filter(d => selectedCategory === d.category), { rows: 5 })); <button id="click-me">Update the table below</button> const btn = document.getElementById('click-me');
const data2 = [
{ id: 1, category: 1 },
{ id: 2, category: 1 },
{ id: 3, category: 1 },
{ id: 4, category: 2 },
{ id: 5, category: 2 }
];
const filteredData2 = Generators.observe(notify => {
const clicked = () => notify(data2.filter(d => Array.from(selectedData).map(d => d.id).includes(d.id)));
btn.addEventListener('click', clicked);
return () => btn.removeEventListener('click', clicked);
}) view(Inputs.table(filteredData2, { rows: 5 })); |
Beta Was this translation helpful? Give feedback.
Resolved. Basically, removing the call to
clicked()
in the function passed toGenerators.observe
made it work as I intended.