Summary: I have an observable controlling a loading page element that hides everything during a long running query. The loading page doesn't show even though the observable is changed before the query. Putting a placeholder setTimeout works, but the page seems to wait for the query to run to update the page.
Edit 3: I should mention that I'm doing this in Node.js.
Edit2: What I want to happen:
1) User clicks button.
2) Loading Screen covers table.
3) Calculations run
4) Loading Screen disappears and table is populated with the results
What is currently happening:
1) User clicks button.
2) Screen freezes for 3-4 seconds as the calculations run.
3) Table is populated with the results
Explanation We have a couple long-ish running queries on our page (takes about 3-4 seconds), and we want to put a loading screen up to hide the controls and inform the people that the page is running.
Here's an extender I wrote (with some help from the internet):
ko.bindingHandlers.Loading = {
init: function (element) {
$(element).append("<div id='loading_wrap' class='loader' style='height:100%; width:100%;text-align:center; margin-top: 20%'><img src='./resources/ajax-loader.gif'><br>Loading, please wait.</div>")
},
update: function (element, valueAccessor) {
var isLoading = ko.utils.unwrapObservable(valueAccessor());
var $element = $(element);
var $children = $element.children(':not(.loader)');
var $loader = $(element).find('.loader');
if (isLoading) {
$children.hide();
$loader.show();
} else {
$children.show();
$loader.hide();
}
}
I attach the bindingHandler to a div containing the results I want to hide until they're ready:
<div class="row table__row" data-bind="Loading:isLoading">
I set the this.isLoading(true) before I run the query and then set it back to false after the query. The following below doesn't work:
this.load = _ => {
var _self = this
this.isLoading(true)
this.search()
this.isLoading(false)
}
However if I put in a timeout, the loading page appears properly.
this.load = _ => {
var _self = this
this.isLoading(true)
setTimeout(function () {
_self.isLoading(false);
}, 3000)
}
I've tried a couple async methods also, but I don't have a good understanding of that. So, how do I make the loading page appear before the query runs and then disappear after the query is finished? Thanks.
Edit: Got some request for our search function. It looks something like this (we're not using Ajax)
this.search = async _ => {
//bunch of filters/calculations on large arrays
this.results(the results of our large calculations)
}