0

I'm trying to figure out what i'm doing wrong here... I've been out of coding for awhile and trying to jump back in for an external application utilizing QuickBase's RESTful API. I'm simply trying to get data from QuickBase to be used outside in an external app to create charts/graphs.

I'm not able to use GET as it gives me only the field names and no data, if I use POST, then I get the values of these fields as well. I'm able to get all the data rendered in the console, but am struggling to get each field rendered to be used in the app.

let headers = {
  'QB-Realm-Hostname': 'XXXXXXXXXXXXX.quickbase.com',
  'User-Agent': 'FileService_Integration_V2.1',
  'Authorization': 'QB-USER-TOKEN XXXXXX_XXXXX_XXXXXXXXXXXXXXXX',
  'Content-Type': 'application/json'
}
let body = {"from":"bpz99ram7","select":[3,6,80,81,82,83,86,84,88,89,90,91,92,93,94,95,96,97,98,99,101,103,104,105,106,107,109,111,113,115,120,123,224,225,226,227,228,229,230,231,477,479,480,481],"sortBy":[{"fieldId":6,"order":"ASC"}],"groupBy":[{"fieldId":40,"grouping":"equal-values"}],"options":{"skip":0,"top":0,"compareWithAppLocalTime":false}}

fetch('https://api.quickbase.com/v1/records/query',
  {
    method: 'POST',
    headers: headers,
    body: JSON.stringify(body)
  })
  
.then(res => {
  if (res.ok) {
    return res.json().then(res => console.log(res));
  }

return res.json().then(resBody => Promise.reject({status: res.status, ...resBody}));
})

.catch(err => console.log(err))

Hoping to get some help getting the data rendered to be used in React, as well as any tips from anyone who's used QuickBase's new API calls in their realm! And I apologize if it's an easy question/issue, haven't been in React for a couple years... and I'm feeling it!

Thanks!

Alex
  • 131
  • 9

2 Answers2

0

On the Quickbase side of things, there isn't the equivalent of 'SELECT *' so to get data for all fields of a table where you don't know the schema (or it changes frequently) you can run a GET on the Fields endpoint: https://developer.quickbase.com/operation/getFields an then use the field IDs in the response to make the POST call to /records/query

Erich Wehrmann
  • 464
  • 2
  • 11
  • Erich, would you have an example of this? So if I'm understanding correctly I'd need to make a GET request, then a POST after. But in my console I'm getting the fields and the data now using just POST, but can't figure out how to use this data (assigning to state props etc) so that I can import this in each component and call those fields as needed when being used. I apologize for my confusion! – Alex Apr 23 '21 at 13:07
  • It is possible to return all fields from a table in a query using 'a' as the value for CLIST. It's part of the documentation for the older API but still works with the new RESTful API. https://help.quickbase.com/api-guide/column_list.html – Nathan Hawe Apr 23 '21 at 13:21
  • I'm able to get all the fields and values with POST. I'm just needing some help and guidance on how to render these and be able to use them in components. This is where being rusty and out of coding for a couple years is taking it's toll. – Alex Apr 23 '21 at 14:09
  • One way to do that might be to use JSX to loop through the array of records returned and transform the payload to the format you need using the map() method – Erich Wehrmann Apr 28 '21 at 18:28
0

A successful response from Quickbase for this call has a property data which is an array of the records returned. Each element of this array is an object where the FID for each field returned is a key for nested object - or objects for some field types - with the field's value. Here's a very contrived example:

{
  "data": [
    {
      "1": {
        "value": "2020-10-24T23:22:39Z"
      },
      "2": {
        "value": "2020-10-24T23:22:39Z"
      },
      "3": {
        "value": 2643415
      }
    }
  ],
  "fields": [
    {
      "id": 1,
      "label": "Date Created",
      "type": "timestamp"
    },
    {
      "id": 2,
      "label": "Date Modified",
      "type": "timestamp"
    },
    {
      "id": 3,
      "label": "Record ID#",
      "type": "recordid"
    }
  ]
}

If you put the data array of the response directly into state with const [quickbaseData, setQuickbaseData] = useState(res.data); for example, you need to keep the structure of the response in mind when accessing that data. If I want to get the value of FID 3 from the first record in the response I would need to use quickbaseData[0]["3"].value. For most field types value will be a string or integer but for some field types it will be an object. You can see the way values are returned for each field type in Field type details.

Depending on your needs you might consider processing the Quickbase response into a new, simpler array/object to use in your application. This is especially helpful if the value being returned needs additional processing such as converting into a Date() object. This would also allow you to make your application API agnostic since other than initially processing the response from Quickbase the rest of your application doesn't have to have any knowledge of how Quickbase returns queried data.

Nathan Hawe
  • 281
  • 3
  • 5
  • Ok, so I should have no issue using POST if my returned data is successful and like you said, in that structure (which it is). Then I should be able to that format to put the data response directly into state. And this would also work for getting all those fields, but I'd have to call each one? I'm wondering if I can assign them, like quickbaseDate[0]["3"].value = quickbaseData.jobName or something like that so I can use it in other components for assigning them. Ultimately I'm attempting to get data, display the data in Line Charts using Chartjs – Alex Apr 23 '21 at 14:32
  • Your best bet is to decide what the best kind of shape for your object in the state is going to be and then transform the Quickbase response to match. So, if you know you need an array of objects with three properties:DateCreated, DateModified, RecordID you can iterate over the Quickbase response and assign the values you want to your new array with something like res.data.forEach(record => {myNewArray.push({DateCreated: record["1"].value, DateModified: record["2"].value, RecordId: record["3"].value})}); or something similar. – Nathan Hawe Apr 23 '21 at 15:17
  • This definiteIy helps, I think I see what you're saying. But still confused on how to edit my code above to start to implement this into my app to get each fields data to be used in other components. – Alex Apr 23 '21 at 15:40