Search

What the Quote?

"Beware the nards of May."

Laura Tripcony

"...and me without a mountain lion."

Thorin Blair

"Necessity may be the mother of invention, but Laziness, it turns out, is it's remote-control-loving, mini-fridge-next-to-the-barcalounger, couch potato father."

Kevin Pettitt

« how to make an XPage a "mashup" - Prologue | Main| how to make an XPage a "mashup" - Step 2 »

how to make an XPage a "mashup" - Step 1

Category xpages
Step 1: Create the Script Library

Create a new server-side JavaScript script library design element (I chose to name the library "xpWeatherAPI"), and add the following code:

var WeatherAPI = function() {
    var locationDocument = database.getView('lookup\\locations').getDocumentByKey(sessionScope.locationfilter);
    var locationId = locationDocument.getItemValueString('OfficeLocationID');
    var temperatureUnit = locationDocument.getItemValueString('OfficeTemperatureUnit');
    var factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
    var parser = factory.newDocumentBuilder();
    var domWeather = parser.parse("http://weather.yahooapis.com/forecastrss?p=" + locationId + '&u=' + temperatureUnit).getDocumentElement();
    
    return {
        getCurrentConditions: function () {
            var weatherUnits = domWeather.getElementsByTagName("yweather:units").item(0);
            var weatherConditions = domWeather.getElementsByTagName("yweather:condition").item(0);
            return [{
                description: weatherConditions.getAttributes().getNamedItem("text").getNodeValue(),
                temperature: weatherConditions.getAttributes().getNamedItem("temp").getNodeValue(),
                conditionImage: 'http://l.yimg.com/a/i/us/we/52/' + weatherConditions.getAttributes().getNamedItem("code").getNodeValue() + '.gif',
                tempUnits: weatherUnits.getAttributes().getNamedItem("temperature").getNodeValue()
            }];
        }
    }
};


Let's take a closer look at what's going on here.
  • We're retrieving the current location from the sessionScope (which is updated whenever a location document is opened) and using that as the key to retrieve the document that defines that location. Then we grab a couple salient bits of information from that document for use later on: namely, two new fields that I added to the form - Yahoo's location ID (or, if a US location, this could be a ZIP code) and a radio button for selecting F/C as the temperature unit.
  • We reference a Java class by entering the full name ("javax.xml.parsers.DocumentBuilderFactory"); SSJS is written almost entirely in JavaScript syntax (formula language being the primary - if not only - exception), but at runtime it's interpreted as Java, so any variables you define actually become Java objects. If you provide the full name (the package plus the class name) then Domino knows exactly what class the object should be; otherwise it guesses... typically rather well. In this case we're using the DocumentBuilderFactory class to create objects that will allow us to parse Yahoo's weather data into something we can display to the user.
  • We construct a URL to the API data, passing in as parameters the data retrieved earlier from the location document.
  • Finally, we return a JSON object containing 4 properties that can be accessed later from our widget. One subtlety that might appear strange: we're wrapping the object inside an array, which at first glance seems unnecessary, because we know we're only returning a single object, so wrapping it inside an array guarantees we'll always be returning a single-index array. Bear with me... you'll see why in Step 2.

Comments

Gravatar Image1 - @Nathan - indeed... expect a followup to that effect sometime next week.

Gravatar Image2 - Performance consideration: perhaps the weather information should only update every X seconds and be stored in an ApplicationScope cache, so the server's not constantly querying Yahoo's weather report?

Gravatar Image3 - Yahoo has deprecated the 'p' parameter but you can use 'w' instead, something like this:
{ Link }

Thanks for posting this, really easy to follow instructions too. There are more more attributes returned if you want to display them, like sunrise, sunset, wind; see { Link }

Post A Comment

:-D:-o:-p:-x:-(:-):-\:angry::cool::cry::emb::grin::huh::laugh::lips::rolleyes:;-)