Help with JSON -> UITable

I’m trying to take the following JSON, passed to Scriptable via Shortcuts as a file, and display it nicely as a table (in shortcuts). I tried to copy a few examples but I’m getting a parse error on line 2 (Unexpected identifier “object”). Any help is appreciated–I can get around in Drafts javascript ok but this is my first time in Scriptable. Also, clearly, I’m not really sure how to work with arrays in JSON

{
   "freezer": [

      {
         "name": "waffles",
         "amount": "4",
      },

      {
         "name": "english muffins",
         "amount": "10",
      },
      {
         "name": "frozen mangos",
         "amount": "3",
      }

   ]
}
const rawJSON = args.shortcutParameter;
const items = JSON.parse(rawJSON);


let table = new UTTable();
let header = new UITableRow();
header.isheader = true
header.addText("Item");
header.addText("Amount");
table.addRow(header);

for (item of items) {
  let row = new UITableRow();
  
  let name = item.name;
  let nameCell = row.addText(name);
  nameCell.widthWeight = 50;
  
  let amount = item.amount;
  let numberCell = row.addText(amount);
  numberCell.widthWeight = 50;
  
  row.height = 30;
  row.cellSpacing = 10;
  
  table.addRow(row);
}

QuickLook.present(table);

I think you may need to get rid of the commas between at the ends of objects in your array so that the JSON can be parsed correctly. i.e.:

{
   "freezer": [

      {
         "name": "waffles",
         "amount": "4"
      },

      {
         "name": "english muffins",
         "amount": "10"
      },
      {
         "name": "frozen mangos",
         "amount": "3"
      }

   ]
}

Good tip! But I’m getting the error still on line two before it hits those items.

I think I’m not parsing the array right, is there a different way to do that?

Ah yes, but line two is trying to parse the JSON, and I believe what you started with is invalid JSON. You can check it in a JSON validator like this one: https://jsonlint.com/

That said, I haven’t tested this out.

JSON.parse() expects a string, so perhaps you don’t need to parse what you have at all if it is already an object.

If you just try const items = rawJSON; does that work?

Hey, that worked. Thanks!

Scriptable now processes the script and presents a table view. However, the table is empty–the header appears, but not any of the rows. I think I’m still having trouble figuring out how to get at the keys in the array. Here’s what I’ve tried that “feels” right:

const items = args.shortcutParameter;


let table = new UITable();
let header = new UITableRow();
header.isheader = true
header.addText("Item");
header.addText("Amount");
table.addRow(header);

for (let item in items.freezer) {
  let row = new UITableRow();
  
  let name = item.name;
  let nameCell = row.addText(name);
  nameCell.widthWeight = 50;
  
  let amount = item.number;
  let numberCell = row.addText(amount);
  numberCell.widthWeight = 50;
  
  row.height = 30;
  row.cellSpacing = 10;
  
  table.addRow(row);
}

QuickLook.present(table);

Ok, found the solution:

const rawJSON = args.shortcutParameter;
const items = rawJSON;



let table = new UITable();
let header = new UITableRow();
header.isheader = true
header.addText("Item");
header.addText("Amount");
table.addRow(header);

items.freezer.forEach(freezer => {
  
  let row = new UITableRow();
    
  let name = freezer.name;
  let nameCell = row.addText(name);
  nameCell.widthWeight = 50;
  
  let amount = freezer.amount;
  let numberCell = row.addText(amount);
  numberCell.widthWeight = 50;
  
  row.height = 30;
  row.cellSpacing = 10;
  
  table.addRow(row);

});

QuickLook.present(table);

Ah, well done! Literally came here to post that but looks like I’m not needed! :slight_smile:

I’m glad you found the solution! :smiley:

I just wanted to follow up on the problem in your initial scripts. Scriptable tries to be “smart” in that when you pass valid JSON as input to a script from Shortcuts, it will automatically parse the JSON and hand you the parsed object. Therefore it’s not necessary to call JSON.parse() on args.shortcutParameter and it will in fact fail.

If for some reason you wanted to parse the JSON yourself, you could pass it as a text (see screenshot) and read the text with args.plainTexts[0].

2 Likes