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 yahoo weather api for get weather feed of single city, now I want to get weather feed for multiple cities in single request, how can I do using yahoo api. I also want to know, is ther any api yahoo provides to get the list of city of any country.

My 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 be able to get weather details for only one city i want to fetch weather details for multiple cities at once.

thanx 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}]}',
    ]