Search code examples
javascriptjsonobjectgoogle-apps-scriptiteration

How to iterate through nested json objects with unique names in Apps Script


Given a json file with nested objects (not arrays) like:

{
    "data": {
        "UniqueName1": {
            "name": "Bob",
            "title": "the man"
        },
        "UniqueOtherName": {
            "name": "Joe",
            "title": "the myth"
        },
        "SuperUniqueName": {
            "name": "Steve",
            "title": "the legend"
        }
    }
}

Using Apps Script, how do I iterate through each unique sub-object to read the common properties therein?

function importLoLChampions() {

  var files = DriveApp.getFilesByName("championFull.json");
  if (files.hasNext()) {
  var file = files.next();
  var jsonString = file.getBlob().getDataAsString();
  var jsonParsed = JSON.parse(jsonString);

  //I can do this:
  Logger.log(jsonParsed.data.UniqueName1.name);
  Logger.log(jsonParsed.data.UniqueOtherName.name);
  Logger.log(jsonParsed.data.SuperUniqueName.name);

  //But I want to do this:
  for(var champion in jsonParsed.data ) 
  {
      Logger.log(champion); //ok so far cause it's treating champion as a string
      for(var championData in champion) //Doesn't work 
      {
        //Champion is treated as a string value, 
        //i.e. seems to have lost object awareness
        Logger.log(championData.name); //output: null
      }
      
  }
  //Or this:
  for(var i=0; i<jsonParsed.data.length); i++)
  {
      Logger.log(jsonParsed.data[i].name); 
      //Fails, treats jsonParsed.data[i] as a string
      //and not an object
  }
    

}

I've been struggling with this for a few hours, can't find a good answer. Is there a way to retrieve jsonParsed.data[i] as an object? Or another way to step through each sub-object to access the keys/values within?


Solution

  • You can use a for...of statement with Object.entries() to iterate over the collection of objects. And you can also leverage destructuring assignment to make the things a little more readable.

    Given:

    var json = {
        "data": {
            "UniqueName1": {
                "name": "Bob",
                "title": "the man"
            },
            "UniqueOtherName": {
                "name": "Joe",
                "title": "the myth"
            },
            "SuperUniqueName": {
                "name": "Steve",
                "title": "the legend"
            }
        }
    }
    

    Then you can do this:

    function iterateOverEntries(json) {
        for (const [uniqueName, { name, title }] of Object.entries(json.data)) {
            console.log(JSON.stringify({
                uniqueName,
                name,
                title
            }, undefined, 4));
        }
    }
    

    Note: Google Apps Script now supports modern Javascript, so try to use let and/or const instead of var, console.log instead of Logger.log, etc.