Consuming JSON Web Data Using Google Sheets

article image

Note: This article has been superseded with Fetching, Filtering, and Sorting JSON APIs in Google Sheets: The Missing Functions which provides a set of Google Sheets functions with additional capabilities.

I’ve said it before, and I’ll say it again.  JSON has become the lingua franca for exchanging data on the web, and we (as developers) need to know how to process JSON data received from RESTful web services so we can be positioned for the present and for the future.

My article on Consuming Node.js Microservices Created with stdlib provided a high-level tour covering several methods of parsing and processing JSON data. Last time, we focused on how to consume JSON data using curl and jq. Today, we’re zooming in and learning more about consuming Web API JSON data using Google Sheets. Once again, we’ll be consuming data from a microservice created with the excellent stdlib platform. Our learning, however, will be universally applicable for consuming Web API JSON data from any http endpoint. I am very impressed with the power and versatility of the Google Sheets platform for consuming JSON data (among many other things).  Let’s get started and experience it firsthand!

Article contents

Weather web API overview – current weather conditions

I created a Weather microservice (see documentation) using stdlib that we’ll use for our tutorial today. Let’s first focus on consuming JSON data using Google Sheets to retrieve the current weather conditions:

The current function accepts two parameters:

  • loc: location (example: San Diego, CA)
  • deg: degree type (F or C) Default is F.

Example: Return a JSON object with the current weather info (deg F) in San Diego

https://thisdavej.azurewebsites.net/api/weather/current?loc=San Diego,CA&deg=F

This will return a JSON object with the following structure:

{
  "temperature": "54",
  "skycode": "29",
  "skytext": "Partly Cloudy",
  "date": "2017-01-21",
  "observationtime": "06:20:00",
  "observationpoint": "San Diego, CA",
  "feelslike": "54",
  "humidity": "69",
  "winddisplay": "15 mph West",
  "day": "Saturday",
  "shortday": "Sat",
  "windspeed": "15 mph",
  "imageUrl": "http://blob.weather.microsoft.com/static/weather4/en-us/law/29.gif",
  "degType": "F"
}

Nice and simple. Let’s use Google Sheets to retrieve the current weather from this cloud-based microservice!

Using built-in IMPORTDATA function

In this first example, we use the built-in IMPORTDATA function to retrieve data from our weather service and display the results. Go ahead and create a Google Sheet as shown here:

  A B
1 City  
2 San Diego, CA =IMPORTDATA(“https://thisdavej.azurewebsites.net/api/weather/current?loc=” & substitute(A2, ” “, “%20”))

Make sure that several cells are empty below cell B2 because the IMPORTDATA function will populate these with the lines of JSON text returned. If the cells below cell B2 are not empty (feel free to try it), Sheets will yield an error indicating that the array could not be expanded because it would overwrite data in the cells below.

After entering the formula in B2, you should see results that look like this:

  A B
1 City  
2 San Diego, CA {
3   temperature: “54”
4   skycode: “29”
5   skytext: “Partly Cloudy”
6   date: “2017-01-21”
7   observationtime: “06:20:00”
8   observationpoint: “San Diego
9   feelslike: “54”
10   humidity: “69”
11   winddisplay: “15 mph West”
12   day: “Saturday”
13   shortday: “Sat”
14   windspeed: “15 mph”
15   imageUrl: “http://blob.weather.microsoft.com/static/weather4/en-us/law/29.gif”
16   degType: “F”
17   }

Next, change the city in cell A2. Google Sheets will re-invoke our weather microservice and show us the results for this new city. We are off to a great start!

Note: If you are using Microsoft Excel instead of Google Sheets, Excel (2013 and higher) ships with the WEBSERVICE function which can be used to invoke URLs and receive JSON data from microservices.

Create CURRENTWEATHER function

Next, let’s create our own custom function in Google Sheets so we can abstract away the URL and make it easier to invoke our weather service. We’ll also start parsing the JSON data returned to retrieve individual fields of data. To accomplish this, click on Tools from the menu and select Script editor.

Google Sheets utilizes JavaScript for developing functions so let’s create a function to retrieve the current weather using JavaScript:

/**
 * Retrieve the current weather for a given city.
 *
 * @param {"San Diego, CA"} location
 *        Location of city where weather information is desired. Can also be a 5 digit zip code.
 * @customfunction
 */
function CURRENTWEATHER(location) {
    location = encodeURI(location);
    var response = UrlFetchApp.fetch("https://thisdavej.azurewebsites.net/api/weather/current?loc=" + location);
    var w = JSON.parse(response.getContentText());
    return w.temperature + '°' + w.degType + ' ' + w.skytext;
}

This function uses the built-in UrlFetchApp.fetch method to fetch the data from our weather service. After fetching the raw JSON text, we parse it, and return some fields from the resulting JSON object.

We declare our function name in upper case which is the standard convention for Google Sheets functions. Finally, you will notice that we include a JSDOC style comment above our function. Sheets uses the JSDOC comment to provide a tooltip on function usage when editing a cell and using the function.

Press Ctrl+S to save your function. Let’s start using it! Modify the spreadsheet as follows:

  A B
1 City  
2 San Diego, CA =CURRENTWEATHER(A2)

You should see the results in the following format:

  A B
1 City  
2 San Diego, CA 54°F Partly Cloudy

Create JSON Handlebars template function

We could declare victory at this point, but we are capable of more. 🙂 Let’s create a custom function that will enable us to use a Handlebars-style templating syntax with the JSON object returned from our weather service. Once again, click on Tools from the menu and select Script editor. Add the following custom function:

/**
 * Parse JSON and render the results in a string template.
 *
 * @param {"url"} url
 *        JSON API data URL
 * @param {"templateText"} template
 *        string template for rendering results
 * @customfunction
 */
function JSONTEMPLATE(url, template) {
    url = encodeURI(url);
    var response = UrlFetchApp.fetch(url);
    var obj = JSON.parse(response.getContentText());

    var result = template.replace(/\{\{\s*(.*?)\s*\}\}/g, function(match, varName) {
        return obj[varName];
    });

    return result;
}

As before, we use the built-in UrlFetchApp.fetch method to fetch the data from our weather service. We parse the JSON object and use regular expressions to substitute in the various attributes of our JSON object using a template. As a side note, regex101.com is very helpful site for creating and testing regular expressions.

Let’s give this templating function a test run to see this awesomeness in action. Modify your sheet as follows:

  A B
1 City {{temperature}} °{{degType}} {{skytext}}
2 San Diego, CA =JSONTEMPLATE(“https://thisdavej.azurewebsites.net/api/weather/current?loc=” & A2,B1)

Please note our template in cell B1. The JSON attributes of interest are enclosed in double curly braces (Handlebars syntax). Invoke the function and you will see something like this:

  A B
1 City {{temperature}} °{{degType}} {{skytext}}
2 San Diego, CA 54°F Partly Cloudy

Weather web API overview – forecast weather conditions

Let’s now create some custom functions to help us with forecast weather conditions. This will not only help us in our personal life to understand the upcoming weather expected, but it will also teach us about handling JSON object arrays since the new forecast Web API we will use returns an array of JSON objects, one for each of the five days in the upcoming weather forecast.

The forecast function accepts two parameters:

  • loc: location (example: San Diego, CA)
  • deg: degree type (F or C) Default is F.

Example: Return a JSON object with weather forecast information (deg F)

https://thisdavej.azurewebsites.net/api/weather/forecast?loc=San Diego,CA&deg=F

This will return a JSON object with the following structure:

[
  {
    "low": "53",
    "high": "59",
    "skycodeday": "29",
    "skytextday": "Partly Cloudy",
    "date": "2017-01-20",
    "day": "Friday",
    "shortday": "Fri",
    "precip": "0",
    "degType": "F"
  },
  {
    "low": "54",
    "high": "60",
    "skycodeday": "34",
    "skytextday": "Mostly Sunny",
    "date": "2017-01-21",
    "day": "Saturday",
    "shortday": "Sat",
    "precip": "20",
    "degType": "F"
  },
  {
    "low": "55",
    "high": "61",
    "skycodeday": "26",
    "skytextday": "Cloudy",
    "date": "2017-01-22",
    "day": "Sunday",
    "shortday": "Sun",
    "precip": "100",
    "degType": "F"
  },
  {
    "low": "50",
    "high": "57",
    "skycodeday": "11",
    "skytextday": "Rain Showers",
    "date": "2017-01-23",
    "day": "Monday",
    "shortday": "Mon",
    "precip": "100",
    "degType": "F"
  },
  {
    "low": "48",
    "high": "57",
    "skycodeday": "34",
    "skytextday": "Mostly Sunny",
    "date": "2017-01-24",
    "day": "Tuesday",
    "shortday": "Tue",
    "precip": "90",
    "degType": "F"
  }
]

How awesome is that? Let’s use Google Sheets to render information based on this weather forecast API.

Display rows of JSON data using a template

We’ll create a Google Sheets function to display the next five days of the weather forecast and format each line using a template. As before, click on Tools from the menu and select Script editor. Add the following custom function:

function JSONROWSTEMPLATE(url, template) {
    url = encodeURI(url);
    var response = UrlFetchApp.fetch(url);
    var obj = JSON.parse(response.getContentText());

    var results = obj.map(function(row) {
        return template.replace(/\{\{\s*(.*?)\s*\}\}/g, function(match, varName) {
            return row[varName];
        });
    });
    return results;
}

As in previous functions, we use the built-in UrlFetchApp.fetch method to fetch the data from our weather service. We also parse the JSON object and use regular expressions to substitute in the various attributes of our JSON object using a template. Since the JSON data is returned as an array, we use the JavaScript map function to process our template and substitute in values for each forecast day. Google made an excellent design choice by including JavaScript as the language for creating custom Sheets functions! This provides lots of power and flexibility.

Let’s try our new function. Make these changes to your sheet:

  A B
1 City {{shortday}} {{low}}-{{high}}°{{degType}} {{skytextday}} ~ Rain: {{precip}}%
2 San Diego, CA =JSONROWSTEMPLATE(“https://thisdavej.azurewebsites.net/api/weather/forecast?loc=” & A2,B1)

Once again, we create a template in cell B1. The JSON attributes of interest for each forecast day (including rain probability) are enclosed in double curly braces (Handlebars syntax). Let’s give it a try! Make sure you have a few cells free below B2 since our function will occupy a cell for each forecast day. You should see something like this:

  A B
1 City {{shortday}} {{low}}-{{high}}°{{degType}} {{skytextday}} ~ Rain: {{precip}}%
2 San Diego, CA Fri 53-59°F Partly Cloudy ~ Rain: 0%
3   Sat 54-60°F Mostly Sunny ~ Rain: 20%
4   Sun 55-61°F Cloudy ~ Rain: 100%
5   Mon 50-57°F Rain Showers ~ Rain: 100%
6   Tue 48-57°F Mostly Sunny ~ Rain: 90%

Fantastic! We are successfully processing arrays of JSON objects and rendering the results using a Handlebars-like syntax.

Create function to handle JSON object containing either an array of objects or a single object

We can make a very small change to the custom function we created in the previous section to handle JSON objects containing either an array of objects or a single object. Replace the JSONTEMPLATE we created a while back with the following code:

/**
 * Parse JSON and render the results in a string template.
 *
 * @param {"http://path/to/myapi"} url
 *        JSON API data URL
 * @param {"This is {{item1}}."} template
 *        string template for rendering results
 * @customfunction
 */
function JSONTEMPLATE(url, template) {
    url = encodeURI(url);
    var response = UrlFetchApp.fetch(url);
    var obj = JSON.parse(response.getContentText());

    if (!Array.isArray(obj)) {
        obj = [obj];
    }

    return obj.map(function(row) {
        return template.replace(/\{\{\s*(.*?)\s*\}\}/g, function(match, varName) {
            return row[varName];
        });
    });
}

Please note lines 15-17. If the JSON returned does not include an array of objects, we “array-ify the object (i.e. create an array containing the one object) so it can be processed using the map function in the next lines. This one small change gives us a big win since it enables our JSONTEMPLATE to be more versatile and able to handle both arrays of objects and single objects!

Create function to sort JSON objects

Why not sort JSON objects while we are at it? Add the following custom code in the Script Editor:

var sort_by = function(field, reverse, primer) {
    var key = primer ? function(x) { return primer(x[field]) } : function(x) { return x[field] };
    reverse = !reverse ? 1 : -1;
    return function(a, b) {
        return a = key(a), b = key(b), reverse * ((a > b) - (b > a));
    }
}

/**
 * Parse and sort JSON object and render the results in a string template.
 *
 * @param {"url"} url
 *        JSON API data URL
 * @param {"template"} template
 *        string template for rendering results
 * @param {"sortField"} sortField
 *        name of field to use for sorting
 * @param {"decendingOrder"} descendingOrder
 *        set to true for descending order. Default: false
 * @param {"primer"} primer
 *        function to apply to values before sorting. Example: parseFloat
 * @param {"takeNum"} takeNum
 *       the number of sorted results to return. Default: all
 * @customfunction
 */
function JSONTEMPLATE_SORTED(url, template, sortField, descendingOrder, primer, takeNum) {
    url = encodeURI(url);
    var response = UrlFetchApp.fetch(url);
    var obj = JSON.parse(response.getContentText());

    if (!Array.isArray(obj)) {
        obj = [obj];
    }

    var fnPrimer = eval(primer)

    obj.sort(sort_by(sortField, descendingOrder, fnPrimer));

    var sortedObj = obj.map(function(row) {
        return template.replace(/\{\{\s*(.*?)\s*\}\}/g, function(match, varName) {
            return row[varName];
        });
    });

    var result;
    if (takeNum === undefined)
        result = sortedObj;
    else
        result = sortedObj.slice(0, takeNum);
    return result;
}

We’ve added several additional concepts. A sort_by function is utilized to help us sort the array of objects. After retrieving and parsing the JSON data, we sort the objects in the array and render the results using our template.

Let’s see this new function in action. Pay attention to the parameters supplied to the function as this will help solidify your understanding of the custom function code above. Make these changes to your Sheet:

  A B
1 City {{shortday}} {{low}}-{{high}}°{{degType}} {{skytextday}} ~ Rain: {{precip}}%
2 San Diego, CA =JSONTEMPLATE_SORTED(“https://thisdavej.azurewebsites.net/api/weather/forecast?loc=” & A2,B1,”low”,false,”parseFloat”)

We sort the forecast weather data based on low temperatures in ascending order. The parseFloat function is used as a “primer” in our function to sort the values numerically rather than alphabetically. Here are some sample results returned:

  A B
1 City {{shortday}} {{low}}-{{high}}°{{degType}} {{skytextday}} ~ Rain: {{precip}}%
2 San Diego, CA Tue 48-57°F Mostly Sunny ~ Rain: 90%
3   Mon 50-57°F Rain Showers ~ Rain: 100%
4   Fri 53-59°F Partly Cloudy ~ Rain: 0%
5   Sat 54-60°F Mostly Sunny ~ Rain: 20%
6   Sun 55-61°F Cloudy ~ Rain: 100%

Looking good! The JSON rows are sorted based on the low field and returned. Think about the possibilities afforded by this Google Sheets function for any type of JSON object returned containing arrays of objects!

Create function to return min and max values

Finally, we are positioned to create a couple more functions to return the min and max values. Add the following code in the Script Editor:

/**
 * Parse JSON object and return the object containing the max value of a selected field rendered in a string template.
 *
 * @param {"url"} url
 *        JSON API data URL
 * @param {"template"} template
 *        string template for rendering results
 * @param {"sortField"} sortField
 *        name of field to use for sorting
 * @param {"primer"} primer
 *        function to apply to values before sorting. Example: parseFloat
 * @customfunction
 */
function JSONTEMPLATE_MAX(url, template, sortField, primer) {
    return JSONTEMPLATE_SORTED(url, template, sortField, true, primer, 1);
}


/**
 * Parse JSON object and return the object containing the min value of a selected field rendered in a string template.
 *
 * @param {"url"} url
 *        JSON API data URL
 * @param {"template"} template
 *        string template for rendering results
 * @param {"sortField"} sortField
 *        name of field to use for sorting
 * @param {"primer"} primer
 *        function to apply to values before sorting. Example: parseFloat
 * @customfunction
 */
function JSONTEMPLATE_MIN(url, template, sortField, primer) {
    return JSONTEMPLATE_SORTED(url, template, sortField, false, primer, 1);
}

We leverage the previous JSONTEMPLATE_SORTED function we created and supply a takeNum value of 1 as the final parameter to sort ascending (or descending) and return only one value representing the minimum or maximum value respectively.

Let’s retrieve the maximum “high” temperature from the array of forecast weather objects:

  A B
1 City {{shortday}} {{low}}-{{high}}°{{degType}} {{skytextday}} ~ Rain: {{precip}}%
2 San Diego, CA =JSONTEMPLATE_MAX(“https://thisdavej.azurewebsites.net/api/weather/forecast?loc=” & A2,B1,”high”,”parseFloat”)

Here are the results:

  A B
1 City {{shortday}} {{low}}-{{high}}°{{degType}} {{skytextday}} ~ Rain: {{precip}}%
2 San Diego, CA Sun 55-61°F Cloudy ~ Rain: 100%

We have experienced success, and we are able to show the maximum and minimum values of various fields in our JSON data set.

Conclusion

Google Sheets provides amazing versatility for consuming JSON data as we demonstrated with the weather service. The ability to use JavaScript to create custom functions results in a huge win! Join us next time as we use Google Sheets to parse the weather data and send us an email in the morning if rain is expected for the day!

Follow @thisDaveJ (Dave Johnson) on Twitter to stay up to date with the latest tutorials and tech articles.

Additional articles

Consuming Web API JSON Data Using curl and jq
Creating Node.js Microservices with Ease Using Stdlib
Consuming Node.js Microservices Created with Stdlib
Getting Started with YAML in Node.js using js-yaml

Share

20 thoughts on “Consuming JSON Web Data Using Google Sheets

  1. Hi, I’ve implemented your JSONTEMPLATE custom function and next I’ll be experimenting with multiple columns containing templates. Thanks for writing this!

  2. You my friend, ARE THE BEST. Thank you soooo much! I save our service ticket “objects” as JSON in a gsheet for audit trails and this code I refactored to get some reports done for our billing department. Perfect!

    1. Leon-that’s awesome. Glad to hear my tutorial was able to help you in your context of processing JSON objects in gsheets! Thanks for letting me know.

  3. [{
    “result”:[
    {
    “sg_event_id”: “92-OndRfTs6fZjNdHWzLBw”,
    “timestamp”: 1529618395,
    “url”: “https://noname.com?utm_campaign=website&utm_source=sendgrid.com&utm_medium=email”,
    “ip”: “192.168.1.1”,
    “event”: “click”
    },
    {
    “sg_event_id”: “bjMlfsSfRyuXEVy8LndsYA”,
    “timestamp”: 1529618349,
    “url”: “https://noname.com?utm_campaign=website&utm_source=sendgrid.com&utm_medium=email”,
    “ip”: “192.168.1.1”,
    “event”: “click”
    },
    {
    “sg_event_id”: “fru_s2s1RtueuqBMNoIoTg”,
    “timestamp”: 1529618255,
    “url”: “https://noname.com?utm_campaign=website&utm_source=sendgrid.com&utm_medium=email”,
    “ip”: “192.168.1.1”,
    “event”: “click”,
    “id”: “555c1f7c5asdf7000167d87b”
    }
    ]
    }
    ]
    How to work with this?

    1. Hi Umar,

      Here is a modified version of the JSONTEMPLATE function from my post to demonstrate for your use case. (The code indention gets removed since this is a comment so my apologies.) I added a “result” variable near the end to shape the JSON object for your context:


      function JSONTEMPLATE_UMAR(url, template) {
      url = encodeURI(url);
      var response = UrlFetchApp.fetch(url);
      var obj = JSON.parse(response.getContentText());

      if (!Array.isArray(obj)) {
      obj = [obj];
      }

      // Handle for the shape of Umar's JSON object returned
      var result = obj[0].result;

      return result.map(function (row) {
      return template.replace(/\{\{\s*(.*?)\s*\}\}/g, function (match, varName) {
      return row[varName];
      });
      });
      }

      You can then create a template in cell A1:


      {{ip}} -> {{event}}

      In cell A2, enter the following formula:


      =JSONTEMPLATE_UMAR("https://path/to/json/object",A1)

      The rows should appear in the cells below with each row in the JSON object processed using the template you specified in cell A1. You should be good to go!

      Update: I created a gist here which preserves indention for your convenience.

  4. This is great! Thanks so much for putting together. Question: You mention above that the parseFloat function is used as to sort the values numerically rather than alphabetically. How would it be used if I want to sort values alphabetically?

    1. You can call the function without the parseFloat parameter to sort alphabetically. For example, instead of:

      =JSONTEMPLATE_SORTED(“https://f.stdlib.com/thisdavej/weather/forecast?loc=” & A2,B1,”low”,false,”parseFloat”)

      call it using:

      =JSONTEMPLATE_SORTED(“https://f.stdlib.com/thisdavej/weather/forecast?loc=” & A2,B1,”low”,false)

  5. Hi Dave, this looks like just what I’ve been looking for to parse handball matches and use them in Google Sheets. I’m struggling though with the data, and I’m wondering if I might need another type of Regex to get the individual data I need?

    Here’s a sample of what I’m getting:
    [{“Dato”:”31.03.2019″,”Tid”:”10:00″,”Turnering”:{“Text”:”Jenter 12 Nivå 1 – B 3 Sluttspill”,”Url”:”http://wp.nif.no/PageTournamentDetails.aspx?LinkId=386598″},”Hjemmelag”:{“Text”:”Lillestrøm HK”,”Url”:”http://wp.nif.no/PageOrgDetail.aspx?linkId=443562″},”Bortelag”:{“Text”:”Ull/Kisa”,”Url”:”http://wp.nif.no/PageOrgDetail.aspx?linkId=443624″},”Bane”:{“Text”:”Skedsmohallen B”,”Url”:”http://wp.nif.no/PageVenueActivityAreaDetail.aspx?LinkId=9290″}},{“Dato”:”31.03.2019″,”Tid”:”11:00″,”Turnering”:{“Text”:”Jenter 11, Regionserien, avdeling 13″,”Url”:”http://wp.nif.no/PageTournamentDetails.aspx?LinkId=382800″},”Hjemmelag”:{“Text”:”Lillestrøm HK Gul”,”Url”:”http://wp.nif.no/PageOrgDetail.aspx?linkId=473330″},”Bortelag”:{“Text”:”Ull/Kisa Blå”,”Url”:”http://wp.nif.no/PageOrgDetail.aspx?linkId=443327″},”Bane”:{“Text”:”Skedsmohallen B”,”Url”:”http://wp.nif.no/PageVenueActivityAreaDetail.aspx?LinkId=9290″}},{“Dato”:”31.03.2019″,”Tid”:”12:00″,”Turnering”:{“Text”:”Jenter 11, Regionserien, avdeling 27″,”Url”:”http://wp.nif.no/PageTournamentDetails.aspx?LinkId=382804″},”Hjemmelag”:{“Text”:”Lillestrøm HK Rød”,”Url”:”http://wp.nif.no/PageOrgDetail.aspx?linkId=497175″},”Bortelag”:{“Text”:”Frogner Gul”,”Url”:”http://wp.nif.no/PageOrgDetail.aspx?linkId=710550″},”Bane”:{“Text”:”Skedsmohallen B”,”Url”:”http://wp.nif.no/PageVenueActivityAreaDetail.aspx?LinkId=9290″}},{“Dato”:”31.03.2019″,”Tid”:”13:00″,”Turnering”:{“Text”:”Jenter 12 Nivå 1 – B 3 Sluttspill”,”Url”:”http://wp.nif.no/PageTournamentDetails.aspx?LinkId=386598″},”Hjemmelag”:{“Text”:”Lillestrøm HK”,”Url”:”http://wp.nif.no/PageOrgDetail.aspx?linkId=443562″},”Bortelag”:{“Text”:”Stabæk”,”Url”:”http://wp.nif.no/PageOrgDetail.aspx?linkId=443556″},”Bane”:{“Text”:”Skedsmohallen B”,”Url”:”http://wp.nif.no/PageVenueActivityAreaDetail.aspx?LinkId=9290″}},{“Dato”:”31.03.2019″,”Tid”:”15:10″,”Turnering”:{“Text”:”Jenter 15 Nivå 2 – B 4 Sluttspill”,”Url”:”http://wp.nif.no/PageTournamentDetails.aspx?LinkId=386651″},”Hjemmelag”:{“Text”:”Lillestrøm HK 2″,”Url”:”http://wp.nif.no/PageOrgDetail.aspx?linkId=497641″},”Bortelag”:{“Text”:”Kolbotn 3″,”Url”:”http://wp.nif.no/PageOrgDetail.aspx?linkId=496924″},”Bane”:{“Text”:”Skedsmohallen B”,”Url”:”http://wp.nif.no/PageVenueActivityAreaDetail.aspx?LinkId=9290″}}]

    Here’s the url to get this result: https://wp.nif.no/PageMatchAvansert.aspx?autoSearch=true&venueId=2684&fromdate=31.03.2019&todate=31.03.2019&showColumns=1,2,5,6,7,8&showSearchPane=false&showHeader=false&showGenerateUrl=false&showInfoPane=false&showPager=false&showToggleSearch=false&showPrintButton=false&showJsonData=true

    I’d like to extract the “Dato”, “Tid”, “Turnering” (the “text” within), “Hjemmelag” (the “text” within) … you get the picture 🙂

    1. Hi Harald, you have asked an excellent question. Thanks for presenting this additional use case which involves nested JSON properties returned from the Web API like “Turnering.Text”. I developed a new version of my Google Sheets functions for consuming JSON Web APIs which handles these additional requirements and a lot more. I’ll be releasing a blog post next week with more details and documentation, but you can go to my getJSON-google-sheets GitHub repo now and check it out. It will handle the URL you presented above just fine—if you haven’t already arrived at another solution. Let me know if you have issues or it is unclear and I’ll help you out.

      For your example, do this:
      Follow the installation instructions on the README page in the GitHub repo.
      Open a Google Sheet.

      In cell A1, enter the URL.
      In cell A2, enter the following template: {{Dato}} || {{Tid}} || {{Turnering.Text}}

      The “||” syntax in the template will split the answer returned into multiple spreadsheet columns.

      In cell A3, enter: =GETJSON(A1, A2)

      Your answer will appear in cells A3, B3, and C3. 🙂

    1. Hi Pedro, there are a few options here. As one option, you could highlight the cells you want to transform (with the first row containing the field names) and copy and paste into the tsv (tab separated values) textbox over at this website. The resulting JSON will appear. There are also many tools available to convert from CSV to JSON so you could save your Sheet as a CSV and take it from there. Finally, there are ways you can use Google Sheets as a JSON endpoint as explained here.

  6. Hey Dave,

    Sorry for the curve ball . But I don’t know how else to solve. Maybe you would be willing to even point me in the right direction. I’ve spent the day trying to figure this out with no luck.

    I’ve never coded before, but was able to follow your page really well and through a bunch of error got pretty far. Here’s the question:

    I adapted your code to be a google sheet script. The idea is to be able to enter a instagram username and the next cell with populate with the instagram user acct ID. In the example below the correct answer is: 232192182

    Here is the code:
    function INSTAGRAMID(Username) {
    Username = encodeURI(Username);
    var response = UrlFetchApp.fetch(“https://www.instagram.com/” + Username + “/?__a=1”);
    var w = JSON.parse(response.getContentText());
    return w.logging_page_id;
    }

    Here is the source page:
    https://www.instagram.com/therock/?__a=1

    and here is the resulting error prompt:
    SyntaxError: Unexpected token < in JSON at position 0

    And help or even a heading is greatly appreciated.

    Cheers,
    p

  7. I think my problem was similar to one described above. Some responses were coming back as arrays. I don’t know much about coding — but eventually, similar to your response in Dec 2018 — I did the following and it seems to work (for now):

    function JSONTEMPLATE(url, template) {
    url = encodeURI(url);
    var response = UrlFetchApp.fetch(url);
    console.log(“response: “, response);
    var obj = JSON.parse(response.getContentText());
    console.log(“object: “, obj);
    // if the object is an Array, return the first object within the Array — wish I read the UMAR response first, but this is clean
    if(Array.isArray(obj)) {
    obj = obj[0];
    console.log(“obj_new: “, obj);
    }
    // The rest of Richard’s handy script stays the same
    console.log(“varName: “, template)
    var result = template.replace(/\{\{\s*(.*?)\s*\}\}/g, function(match, varName) {
    return obj[varName];
    });
    return result;
    }

Leave a Reply

Your email address will not be published. Required fields are marked *