I am having a problem getting some queries and functions to run in the correct order. Suppose I have 2 functions that create 2 dropdowns (dropdown_a
, dropdown_b
). Sequentially create_a(items)
must first be called before create_b(items)
. In fact, create_a(items)
creates dropdown_a
and then contains an on('change')
event that triggers function_b(items)
, which in turn, creates dropdown_b
. To get the parameter items
for each of these functions, I first must query a REST
service. Without pasting a ton of code (it's huge), the workflow would look this:
function create_a(items):
var projectNode = dom.byId("projectDropdown");
...
var projectSelector = new Select({
name: "projectSelect",
id: "projectSelect",
options: projectsOptions
}).placeAt(projectNode).startup();
dijit.byId('projectSelect').on('change', function (e) {
var subprojectQuery = new esriQuery();
... // creates a query to get subproject items
subprojectAccessQueryTask.execute(subprojectQuery,
function (results) {
let records = results.features;
createSubprojectDropdown(records); // calls the subproject function
},
function (error) {
console.log("query error: ", error);
}
}); // End of deferred Query Task for Project Name
});
}
function create_b(items) {
var subprojectNode = dom.byId("subprojectDropdown");
var p = registry.byId('subprojectSelect');
if (p) {
p.destroyRecursive();
}
var subprojectSelector = new Select({
name: "subprojectSelect",
id: "subprojectSelect",
options: subprojectsOptions
}).placeAt(subprojectNode).startup();
dijit.byId('subprojectSelect').on('change', function (e) {
thisWidget.loadData(e, proj_type_obj);
});
thisWidget.loadData();
}
// Query 1 - Projects
var queryTask_a = new QueryTask();
queryTask_a.execute(query_a_obj,
function (results) {
...
create_a(results);
...
}
});
// Query 2 Subprojects
var queryTask_b = new QueryTask();
queryTask_a.execute(query_a_obj,
function (results) {
...
create_b(results);
...
}
});
Now I want to trigger the Projects dropdown on('change')
event based on a value
. When that is complete, I want to do the same for the subprojects dropdown. Like this:
var info_proj_name = "project_a";
var subproj_name = "subproject_b"
dijit.byId('projectSelect').set("value", info_proj_name);
dijit.byId('subprojectSelect').set("value", subproj_name);
The problem is, at this point, dijit.byId('projectSelect')
may/may not exists in the dom
, .set
may/may not be a function, etc...It seems that if I run it as above slowly in Chrome Devtools
it works but when I let the application run as-is, there seems to be a lag in the time the dropdowns are created and populated by the query and when the dijit.byId('projectSelect').set("value", info_proj_name);
gets called. Since I am using Dojo/Dijit
already, I am trying to apply a promise/callback
functionality like Deferred
to run everything in order:
1) query a (get list of items for project dropdown)
2) call create_a function (create project dropdown, trigger subproject process)
3) query b (get list of items for subproject dropdown)
4) call create_b function (create subproject dropdown)
5) select an option from projects dropdown (triggers subprojects query and subrprojects dropdown)
6) select and option from subprojects dropdown (triggers subprojects on(change) event)
I am somewhat confused as to how I could apply something like this to chain these things together. Any suggestions on how to set this up in a general sense?
To avoid having to re-architecture the whole thing, you might try with dojo/ready (see here for documentation):
ready(function(){
dijit.byId('projectSelect').set("value", info_proj_name);
ready(function(){
dijit.byId('subprojectSelect').set("value", subproj_name);
});
});
If that does not work, the next possibility is setTimeout:
setTimeout(function(){
dijit.byId('projectSelect').set("value", info_proj_name);
setTimeout(function(){
dijit.byId('subprojectSelect').set("value", subproj_name);
}, timeout1);
}, timeout2);
then do the guess work on timeout1 and timeout2, and cross your fingers above all if those statements need to wait until a server response.
Now of course re-architecturing will help. I would start with moving the call to queryTask_b.execute inside the queryTask_a.execute callback, and after the create_a statement, which respects your 1, 2, 3, 4 order above.