Context and goal
I have two fetch
/then
chains that build elements that I need for an event handler.
The first chain loads data to build a <select>
element. Some options are selected by default. The function in the then
does not return anything. It only creates the <select>
element in the DOM.
fetch("data/select.json")
.then(response => response.json())
.then(data => {
// populate select options
});
The second chain loads data to draw several charts using Chartist.
fetch("data/chartist.json")
.then(response => response.json())
.then(data => Object.keys(data).forEach(x =>
// draw charts using Chartist
new Chartist.Line(`#${x}`, { "series": data[x] });
));
Finally, I need to add an event handler to each chart object (on the "created"
event using Chartist's on
method). The handler function needs to get the values selected in the <select>
element that was built in the first fetch
/then
chain. Since "created"
is emitted each time the charts are (re)drawn (e.g. chart creation, window resize, etc.), the user may have selected different values than the default ones in the meantime. Therefore, I can not just use a static array containing the default values. Instead, I get the selected values from the properties of the <select>
element in the DOM (i.e. selectElement.selectedOptions
), so I need to wait for the <select>
element to be ready.
What I tried
Currently, I add the event handler to each chart object in the second fetch
/then
chain. However, this fails when the code that get the selected options is executed before the <select>
element is ready.
fetch("data/chartist.json")
.then(response => response.json())
.then(data => Object.keys(data).forEach(x => {
// draw charts using Chartist
const chart = new Chartist.Line(`#${x}`, { "series": data[x] });
// add an event handler to the charts
chart.on("created", () => {
// get the values selected in the <select> and use it
});
}));
I also tried to nest the second fetch
/then
chain in the first one or to add a timeout. This is not optimal because it waste time by not fetching the data asynchronously.
Question
I guess the cleanest solution would be to extract the event handler from the second fetch
/then
chain, let both fetch
/then
chains run asynchronously, and wait only before adding the event handler. Is it a good approach?
If yes, I think that I need to make the then
s return promises and wait (e.g. using Promise.all
). One promise should return the chart objects without missing any event (notably the first "created"
event emitted on chart creation), so I could extract the event handler outside of the second fetch
/then
chain.
I read many related questions on SO (e.g. about asynchronous programming and promises), as well as the meta thread about closing such questions. I understand that the theory have already been thoroughly explained several times, but I did not manage to implement a clean solution to my problem despite reading carefully (beginner here). Any hint would be much appreciated.
from Build an event handler using elements from two fetch/then chains
No comments:
Post a Comment