Get JSONP data from a website

Hello all,

I am pretty new to electric imp and the squirrel language in general. I apologize in advance for my blatant ignorance but i need some help.

I am trying to create my own goal light using the electric imp. I have looked at other forum posts pertaining to goal lights but they don’t seem to have the solution I’m looking for. What I am trying to do is get the JSON data from either of these websites:

http://sports.espn.go.com/nhl/bottomline/scores

http://live.nhle.com/GameData/RegularSeasonScoreboardv3.jsonp

into the agent. The NHL URL contains the JSONP extension, for which i could not find info on how the electric imp retrieves the JSON data from a JSONP.

Here is the code I have so far

`// At the start, print a message to say we’re online, and print the agent URL:
server.log(“Goal Light Agent is Online :)” + http.agenturl());

local req = http.get("http://live.nhle.com/GameData/RegularSeasonScoreboardv3.jsonp?loadScoreboard=?", {});
local resp = req.sendsync();
local matchData = http.jsondecode(resp.body);

server.log(req);`

Here is sort of what my goal for this project is:

Agent retrieves JSON data -> JSON parsed -> Look at current date -> Look for certain team within the current dates games -> Put agent into “listen” mode during the game to poll the website to look for goal change -> send command to imp to switch on light once goal is scored

Any help you could provide, resources, code, guidance in the right direction, is very much appreciated.

Here’s a parsejsonp function I whipped up… it essentially strips out the padded part of the json. It’s designed to work with jsonp regardless of whether it’s terminated with a semicolon or not, and is also tested against the NHL feed you supplied.

The result will be an object, similar to http.jsondecode().

Let me know if you have any questions about it :slight_smile:

`const NHL = “http://live.nhle.com/GameData/RegularSeasonScoreboardv3.jsonp”;

/**************************************************

  • Function: parsejsonp

  • Parameters: body - the body of the response (the jsonp function)

  • Returns: The parse data as an object (if successful)

  •          Throws an error if parsing failed
    
  • How it works:

  • We know jsonp looks like this: functionName(json)

  • So to extract and parse the json, we need to find

  • the strip out the functionName, the first “(”

  • plus the last “)” and a “;” if it exists
    */
    function parsejsonp(body) {
    try {
    // grab the body, and remove leading/trailing whitespace
    local jsonp = strip(body);
    local length = jsonp.len();

     // find the start of the data
     local jsonStart = jsonp.find("(") + 1;
     
     // find the end of the data
     local jsonEndOffset = -1;   // len() -1 if no semicolon
     if (jsonp[length-1] == ';') {
         jsonEndOffset = -2;     // len() -2 if a semicolon is present
     }
     
     // slice the data
     local json = jsonp.slice(jsonStart, jsonp.len() + jsonEndOffset);
     local data = http.jsondecode(json);
     
     return data;
    

    } catch(ex) {
    throw("Error parasing data: " + ex);
    }
    }

function shouldParseJsonpWithNoSemicolon() {
local testData = “test({“a”: 1})”;
local result = parsejsonp(testData);
server.log(“shouldParseJsonpWithNoSemicolon: passed”);
}

function shouldParseJsonpWithSemicolon() {
local testData = “test({“a”: 1});”;
local result = parsejsonp(testData);
server.log(“shouldParseJsonpWithSemicolon: passed”);
}

function shouldParseJsonpFromNHL() {
local testData = http.get(NHL).sendsync().body;
local result = parsejsonp(testData);
server.log(“shouldParseJsonpFromNHL: passed”);
}

function test() {
shouldParseJsonpWithNoSemicolon();
shouldParseJsonpWithSemicolon();
shouldParseJsonpFromNHL();
}

test();`

Wow, thank you very much @beardedinventor! I will definitely give this code a try once im back in the studio. :slight_smile:

Did it work?

Well, DID IT!?!?!