javascriptnode.jsyahooyahoo-weather-api

Using Node js, how to get weather feeds for multiple cities in single request using yahoo weather api


I'm using the Yahoo Weather API to get weather feeds for a single city; now I'd like to get weather feeds for multiple cities in a single request; how can I achieve this using the Yahoo API? I also want to know if Yahoo has an API for retrieving a list of cities in any country.

weather.js

 import OAuth from 'oauth';

    const header = {
      "X-Yahoo-App-Id": "myappid"
    };
    
   const request = new OAuth.OAuth(
         null,
         null,
         'myconsumerkey',
         'myconsumersecret',
         '1.0',
         null,
         'HMAC-SHA1',
         null,
         header
        );

request.get('https://weather-ydn-yql.media.yahoo.com/forecastrss?w=713169&format=json', null,null, function (err, data, result) {
       if (err) {
         console.log(err);
       } else {
         console.log(data)
       }
     });

Using this code, I can receive weather data for only one city; however, I want to get weather data for multiple cities at once.

Thank you in advance!


Solution

  • So reading the documentation it doesn't seem possible to send a batch of locations to the Yahoo Weather API. But what you can do is .map() over an array of locations and make multiple requests.

    https://developer.yahoo.com/weather/documentation.html#params

    Since OAuth 1.0 is a callback, I've wrapped that with a new Promise(), which will give us an array of unfulfilled promises. Then finally, Promise.all() method returns a single Promise that fulfills when all of the promises passed as an iterable have been fulfilled.

    const OAuth = require('oauth')
    
    const header = {
        'X-Yahoo-App-Id': 'your-app-id',
    }
    
    const request = new OAuth.OAuth(null, null, 'your-consumer-key', 'your-consumer-secret', '1.0', null, 'HMAC-SHA1', null, header)
    
    const locations = ['pittsburgh,pa', 'london']
    
    const getWeatherData = () =>
        Promise.all(
            locations.map(
                location =>
                    new Promise((resolve, reject) =>
                        request.get(`https://weather-ydn-yql.media.yahoo.com/forecastrss?location=${location}&format=json`, null, null, (err, data) => {
                            if (err) return reject(err)
                            return resolve(data)
                        })
                    )
            )
        )
    
    const main = async () => {
        const test = await getWeatherData()
    
        console.log(test)
    }
    
    main()
    

    I have tested this with the API and here is an example response for the code above.

    [
        '{"location":{"city":"Pittsburgh","region":" PA","woeid":2473224,"country":"United States","lat":40.431301,"long":-79.980698,"timezone_id":"America/New_York"},"current_observation":{"wind":{"chill":32,"direction":280,"speed":5.59},"atmosphere":{"humidity":70,"visibility":10.0,"pressure":29.03,"rising":0},"astronomy":{"sunrise":"6:42 am","sunset":"7:59 pm"},"condition":{"text":"Partly Cloudy","code":30,"temperature":37},"pubDate":1586862000},"forecasts":[{"day":"Tue","date":1586836800,"low":38,"high":45,"text":"Mostly Cloudy","code":28},{"day":"Wed","date":1586923200,"low":32,"high":47,"text":"Partly Cloudy","code":30},{"day":"Thu","date":1587009600,"low":31,"high":45,"text":"Partly Cloudy","code":30},{"day":"Fri","date":1587096000,"low":35,"high":42,"text":"Rain And Snow","code":5},{"day":"Sat","date":1587182400,"low":35,"high":51,"text":"Scattered Showers","code":39},{"day":"Sun","date":1587268800,"low":42,"high":59,"text":"Rain","code":12},{"day":"Mon","date":1587355200,"low":43,"high":55,"text":"Mostly Cloudy","code":28},{"day":"Tue","date":1587441600,"low":37,"high":58,"text":"Partly Cloudy","code":30},{"day":"Wed","date":1587528000,"low":44,"high":61,"text":"Partly Cloudy","code":30},{"day":"Thu","date":1587614400,"low":50,"high":59,"text":"Mostly Cloudy","code":28}]}',
        '{"location":{"city":"London","region":" England","woeid":44418,"country":"United Kingdom","lat":51.506401,"long":-0.12721,"timezone_id":"Europe/London"},"current_observation":{"wind":{"chill":46,"direction":70,"speed":6.84},"atmosphere":{"humidity":50,"visibility":10.0,"pressure":30.27,"rising":0},"astronomy":{"sunrise":"6:04 am","sunset":"7:58 pm"},"condition":{"text":"Mostly Sunny","code":34,"temperature":49},"pubDate":1586862000},"forecasts":[{"day":"Tue","date":1586818800,"low":38,"high":54,"text":"Partly Cloudy","code":30},{"day":"Wed","date":1586905200,"low":34,"high":62,"text":"Mostly Sunny","code":34},{"day":"Thu","date":1586991600,"low":38,"high":68,"text":"Partly Cloudy","code":30},{"day":"Fri","date":1587078000,"low":45,"high":62,"text":"Rain","code":12},{"day":"Sat","date":1587164400,"low":45,"high":60,"text":"Rain","code":12},{"day":"Sun","date":1587250800,"low":42,"high":63,"text":"Partly Cloudy","code":30},{"day":"Mon","date":1587337200,"low":44,"high":64,"text":"Scattered Showers","code":39},{"day":"Tue","date":1587423600,"low":44,"high":66,"text":"Partly Cloudy","code":30},{"day":"Wed","date":1587510000,"low":45,"high":67,"text":"Mostly Cloudy","code":28},{"day":"Thu","date":1587596400,"low":44,"high":65,"text":"Mostly Cloudy","code":28}]}',
    ]