Batch Update "Display As" Property

  • 0
  • 1
  • Question
  • Updated 7 months ago
  • In Progress
It is my understanding that you cannot use the QuickBase API to change a field's type. However, API_SetFieldProperties has been quite the time saver when working with large groups of similar fields. 

One thing I haven't been able to do, is find a way to update the "Display As" field property via the QuickBase API. Is there a reason this field is not updatable via the API?

Or is the API parameter named as such that it would not be readily apparent?

Thanks!
Photo of Nick Wade

Nick Wade

  • 172 Points 100 badge 2x thumb
  • good, API works well for the most part

Posted 7 months ago

  • 0
  • 1
The field name is the "Display As". I wish there was a different field for "Display As" that we can use for forms and reports, dynamic filters and so on, but alas, Quick Base doesn't have that yet. I have requested for this feature on User voice though.
Photo of Ⲇanom the ultimate (Dan Diebolt)

Ⲇanom the ultimate (Dan Diebolt), Champion

  • 30,074 Points 20k badge 2x thumb
I have no clue what you mean by "Display As" field property. Can you post a screenshot displaying this field property?

In regards to the API, it is a limitation to think that calling an API method (eg ?act=API_*is any different that calling any URL method. With appropriate access, you can call any "native" URL method (eg ?a=er), or "internal" URL methods (eg ?a=QBI_*, ?a=JBI_*) as conveniently as calling any API method (eg ?act=API_*).

The only substantial distinction between an API method (eg ?act=API_*) and any other URL method is that QuickBase has published the API methods and implicitly will support them as published for the foreseeable future whereas the other URL methods may change over time. But the reality is  these other URL methods don't change very frequently over time.
Photo of Nick Wade

Nick Wade

  • 172 Points 100 badge 2x thumb
Fields > Specific Field > Properties > Display


Thanks for pointing that out. At the time of writing this post, the URL method being called when modifying a field via the QuickBase UI is called DoModFieldForm, and there is a parameter called "treatas" that accepts the following values 
  • 0: Simple Number
  • 1: Start Rating
  • 2: Currency
  • 3: Percent
My original question should have been phrased more like "why isn't the treatas (Display as) field included in the QuickBase API documentation", but again, thank you for pointing out the ability to utilize native / internal URL methods.
Photo of Ⲇanom the ultimate (Dan Diebolt)

Ⲇanom the ultimate (Dan Diebolt), Champion

  • 30,074 Points 20k badge 2x thumb
Just create your own API modeled off the native action GenChangeFieldType. This is called the Be The API technique modeled off of the Be The Bike patent:


Be The Bike! From the Patently Absurd Inventions Archive
http://totallyabsurd.com/bethebike.htm

Towards this end write a function which returns a promise with this signature:
function changeFieldType(dbidTable, fid, type) {
  return Promise.resolve(
    $.get(dbidTable, {
      a: "GenChangeFieldType",
      BUT: "CONVERT+DATA",
      D0: type,
      fid: fid
    })
  ).then(function() {
    return "it certainly worked!";
  });
}
Set the parameters:
var dbidTable = "your table dbid";
var fid = "6";
var type = "PC";
And call the function:
changeFieldType(dbidTable, fid, type)
  .then(function(response) {
    console.log(response);
  });
Pastie Database
https://haversineconsulting.quickbase.com/db/bgcwm2m4g?a=dr&rid=681
(Edited)
Photo of Ⲇanom the ultimate (Dan Diebolt)

Ⲇanom the ultimate (Dan Diebolt), Champion

  • 30,074 Points 20k badge 2x thumb
I wanted to add to my answer as I did not address the issue of using the code for a "Batch Update" as your title mentioned. The code I posted included a function changeFieldType() that changed the type of a single field. You might think that you could just call this function multiple times to make a batch update to multiple fields. However, if you tried this on a large number of fields you might well encounter a problem as your browser may choke when making so many simultaneous network requests. Luckily, there is a simple solution which can be extended and applied to much larger automation pipelines.

Note that the original code always returned a promise that resolved to the string "it certainly worked!". This was done because the native action GenChangeFieldType changes the field type on the backend and returns an unstructured HTML page as opposed to a well structured XML response. We could rip through the returned HTML page and scrape out some information indicating the action completed successfully or not but it probably isn't worth the extra effort because short of an error in the parameters the operation will almost always be successful. If you did want to process the HTML response the function would look something like this: 
function changeFieldType(dbidTable, fid, type) {
  return Promise.resolve(
    $.get(dbidTable, {
      a: "GenChangeFieldType",
      BUT: "CONVERT+DATA",
      D0: type,
      fid: fid
    })
  ).then(function(response) {
    return <extract some data from the HTML response>;
  });
}
If we wanted to do a batch update on multiple fields we might have a array of fids:
var fids = ["6", "7", "8", "9"];
Then we might call changeFieldType() multiple times in succession like this:
changeFieldType(dbidTable, fid[0], type)
  .then(function(response) {
    console.log(response);
    return changeFieldType(dbidTable, fid[1], type)
  })
  .then(function(response) {
    console.log(response);
    return changeFieldType(dbidTable, fid[2], type)
  })
  .then(function(response) {
    console.log(response);
    return changeFieldType(dbidTable, fid[3], type)
  })
  .then(function(response) {
    console.log(response);
  })
But clearly this approach will not work if you have say 100 fields to convert as the code would be repetitious and lengthy. If only we could use some type of a for loop to structure this chain of promises.

Well it turns out that there is a new feature in JavaScript that allows you to do precisely this. Here is some additional code that uses something called an "asynchronous generator" function named changeFieldTypes (nb this function name is plural and it takes an array of fids):
async function* changeFieldTypes(dbidTable, fids, type) {
  for (var i = 0; i < fids.length; i++) {
    var fid = fids[i];
    yield await changeFieldType(dbidTable, fid, type);
  }
}
for await (const response of changeFieldTypes(dbidTable, fids, type)) {
  console.log(response);
}
I will skip the technical details in this post but you can read more about Asynchronous Generators here:

Asynchronous Generators and Pipelines in JavaScript
https://dev.to/nestedsoftware/asynchronous-generators-and-pipelines-in-javascript--1h62

The bottom line is that using these techniques (jQuery and ES6 Promises along with Asynchronous Generators etcyou can create complex pipelines of processing to automate just about anything and the resulting code will be extremely short.

Pastie Database
https://haversineconsulting.quickbase.com/db/bgcwm2m4g?a=dr&rid=682
(Edited)