Search code examples
google-apps-scriptnested-object

Google Apps Script: How to get values from all dynamic keys in deeply nested object


Trying to retrieve all the dividend values from the object in this url. I'm getting an error, "TypeError: obj.chart.result[0].events.dividends.map is not a function". I'm trying to build a basic coding skill in handling nested objects. What should be changed in this code? Some explanation would be greatly helpful. Thank you!

function test() {
  var url = "https://query1.finance.yahoo.com/v8/finance/chart/VZ?formatted=true&lang=en-US&region=US&interval=1d&period1=1451624400&period2=1672963200&events=div&useYfid=true&corsDomain=finance.yahoo.com";
  var obj = UrlFetchApp.fetch(url, { muteHttpExceptions: true }).getContentText();
  var obj = JSON.parse(obj);
  var dividend = obj.chart.result[0].events.dividends.map(o => (({ o: { amount } }) => amount));
  console.log(dividend)
}

Solution

  • Your dividends is not an array. It's an object. In the programming space people might call it a hashmap, key-value pair, or map. Since this is JavaScript, might also consider it just JSON.

    The way you're trying to use it though, using .map() is a method on arrays which is completely different from what object is--although an object might be referred to as a map.

    The .map() array method is a for loop that takes a predicate to alter the elements of the array. For example,

    [1,2,3,4,5].map((n) => {return n * 2})
    // returns: [2,4,6,8,10]
    

    Since dividends is some object like...

    {
      12345: {amount: 1, date: 12345678},
      12346: {amount: 1, date: 12345678},
      // etc
    }
    

    Then you might do something like...

    Object.keys(obj.chart.result[0].events.dividends).map((dividend_id) => {
      Logger.log(obj.chart.result[0].events.dividends[dividend_id])
    })
    

    In this example we put the dividends object into Object.keys() which would give back the ids of those dividends like [12345, 12346, 12347, ...].

    In the .map() predicate, (dividend_id) => { /** do stuff like console.log */} we're taking that id and using it to open it's matching key and return the value of that key from dividends.