How To Make Bulk Use Of API?This may come as a surprise to native builders but in the near future everyone will be using the API to manipulate their QuickBase applications and eventually the whole point and click graphical user interface will go away. Yes its true - there will be nothing but API and JavaScript. What a glorious day that will be! To prepare you for this day I thought I would demonstrate how to make bulk use of the API using modern JavaScript. When I say modern JavaScript this will not be an exaggeration as we are going to use the most recent JavaScript features including
asynchronous iterators and a whole bunch of ES6 sugar.
Let's take as a demo the creation of a large number of new fields using the action
API_AddField. You might think you could just wrap a simple for loop around
API_AddField and be done with the task in a jiffy. Unfortunately, if you tried this your browser would slow to a crawl as the for loop would unleash a flood of network calls as fast as the for loop executed. To successfully perform this type of bulk use of the API you have to use some special features in modern JavaScipt to orchestrate and sequence the multiple API calls so as to avoid flooding the network with simultaneous AJAX requests.
Assume we want to add one of each field type to a table and the field's
label and
type are identified by an object similar to this:
const fields = [
{label: "Checkbox", type: "checkbox"},
{label: "Date", type: "date"},
{label: "Duration", type: "duration"},
{label: "Email Address", type: "email"},
{label: "File Attachment", type: "file"},
{label: "List - User", type: "multiuserid"},
{label: "Multi-select Text", type: "multitext"},
{label: "Numeric", type: "float"},
{label: "Numeric - Currency", type: "currency"},
{label: "Numeric - Percent", type: "percent"},
{label: "Numeric - Rating", type: "rating"},
{label: "Phone Number", type: "phone"},
{label: "Report Link", type: "dblink"},
{label: "Text", type: "text"},
{label: "Time Of Day", type: "timeofday"},
{label: "URL", type: "url"},
{label: "User", type: "userid"}
];
And of course we want some type of for loop that will take a
dbid and our
fields object above and on each iteration of the for loop will create the new field and give us access to the
label,
type and
fid of each newly created field:
for <dbidRecords, fields> {
console.log('${label}, ${type}, ${fid}');
}
First, we will need something called an
async function named
addField(dbid, label, type) that will create an
individual field in the table
dbid with the specified
label and
type:
async function addField(dbid, label, type) {
return Promise.resolve(
$.get(dbid, {
act: "API_AddField",
label,
type
})
).then(xml => {
return {
label,
type,
fid: $("fid", xml).text()
}
});
}
It is called an
async function because it will
always return a
promise which when the promise resolves will return the
label,
type and
fid as an object.
Async functions are used with another keyword named
await which basically indicates where the function should temporarily suspend execution until the promise that is being awaited resolves.
In our cases we don't want to create just a
single field, we want to create one field for each element in the fields array. To do this task we will need to create another function
addFields(dbid, fields):
async function* addFields(dbid, fields) {
for (const {label, type} of fields) {
yield await addField(dbid, label, type);
}
}
The type of function is called an
async[chronous] generator and is adorned with an
asterisk (ie
*) after the function keyword and uses the
yield keyword within the function body. The
yield keyword basically indicates where the generator will pause execution and yields its value to the body of the eventual for loop we will be using to perform the ultimate iteration.
Your head may be exploding at this point at the complexity of this script and the number of new constructs being introduced. Fear not, because this construction allows us to iterate over the promises (which create new fields using
API_AddField) with utter simplicity:
for await (const {label, type, fid} of addFields(dbidRecords, fields)) {
console.log('${label}, ${type}, ${fid}');
}
What this new for loop construct does is first call
addFields(dbidRecords, fields) to return an object called an
iterator and then proceeds to loop through the iterator and return the
label,
type and
fid of the newly created field on each iteration of the iterator.
Put it all together with a little additional boilerplate code and you have a general purpose method to create an arbitrary number of new fields of the specified type.
Pastie Databasehttps://haversineconsulting.quickbase.com/db/bgcwm2m4g?a=dr&rid=690Notes:(1) ...