Extracting the final item from a nested array in JavaScript (AirTable Scripting)

Hey folks! I’m new to JavaScript and working on an AirTable project. I’m trying to get info from an API and update my AirTable. The tricky part is getting the most recent vote data, which is the last object in a ‘votes’ array.

Here’s what I’ve got so far:

let apiToken = 'my_secret_token'
let table = base.getTable('Test Bills')
let { records } = await table.selectRecordsAsync()

for (let record of records) {
  let billUpdate = await remoteFetchAsync(`https://api.legiscan.com/?key=${apiToken}&op=getBill&id=${record.name}`)
  let data = await billUpdate.json()
  console.log(data.bill)

  // This part isn't working
  const lastVote = data(data.votes.length - 1)
}

I’m stuck on two things:

  1. How do I correctly set the lastVote variable?
  2. Is there a better way to grab the last object in an array?

I’m getting this error:

TypeError: Cannot read properties of undefined (reading 'length')

Any tips would be awesome! Thanks!

As someone who’s been knee-deep in AirTable scripting, I can relate to your struggle. One thing I’ve learned is that API responses can be tricky beasts. Here’s a tip that’s saved my bacon more times than I can count:

Before diving into the data, always log the full response to see its structure. Something like:

console.log(JSON.stringify(data, null, 2));

This will give you a clear view of how the data is actually structured. Often, the API docs don’t tell the whole story.

For grabbing the last vote, I’ve found this approach pretty reliable:

const lastVote = data.bill?.votes?.slice(-1)[0] || null;

It uses optional chaining to avoid errors if ‘votes’ doesn’t exist, and ‘slice(-1)’ to get the last element. It’s been my go-to for similar situations. Just remember to handle the case where ‘lastVote’ might be null in your subsequent code.

hey jackwolf69, looks like ur almost there. the error might be cuz ‘data.votes’ is undefined. try this:

const lastVote = data.bill.votes && data.bill.votes.length > 0
  ? data.bill.votes[data.bill.votes.length - 1]
  : null;

this checks for votes and returns the last vote. hope it helps!

I’ve encountered similar issues when working with nested API data. Based on your code, it appears the ‘votes’ array is nested within the ‘bill’ object. To access the last vote, you’ll need to adjust your approach slightly:

const lastVote = data.bill.votes && data.bill.votes.length > 0
  ? data.bill.votes[data.bill.votes.length - 1]
  : null;

This checks if ‘votes’ exists and has items before attempting to access the last one. Alternatively, you could use the more concise array method:

const lastVote = data.bill.votes?.at(-1) || null;

This uses optional chaining and the ‘at’ method to safely retrieve the last item. Remember to handle cases where no votes exist in your subsequent code.