-1

As you can see below I'm nesting them, each one depending on the result of the previous. I think it would be better to just chain them together (just have them sequential) but it takes a while for each result to come back and it's asynchronous. When I call the function, the result isn't loaded yet and it returns undefined. How can I make sure that everything is done in the function before I try to get the results?

<!DOCTYPE html>
<head>

</head>

<body>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script type="text/javascript">

/* 
To get endpoint
https://api.weather.gov/points/39.7456,-97.0892

To get office, zone, forecast etc from end point
https://api.weather.gov/gridpoints/TOP/31,80
*/

var tLat = 40.985;
var tLon = -71.696;

stationString = getStationFromLatLon(tLat,tLon);
console.log(stationString);



function getStationFromLatLon(theLat,theLon){

    theURL = 'https://api.weather.gov/points/' + theLat + "," + theLon;
    var obsStationsURL;
    var obsStationURL;

    // This passes in the lat lons and gets the weather observation stations 
    $.getJSON(theURL, function(data){
        console.log(data);

        obsStationsURL = data.properties.observationStations;

        console.log(obsStationsURL);

        // Get the first obsStation using the obsStations URL
        $.getJSON(obsStationsURL, function(data2){

            obsStationURL = data2.observationStations[0];

            console.log(obsStationURL);

            // Get the weather station ID and name using the station URL from previous call
            $.getJSON(obsStationURL, function(data3){
                stationID = data3.properties.stationIdentifier;
                stationName = data3.properties.name;

                console.log(stationID + " " + stationName);
                returnString = stationID + " " + stationName;
                return returnString; 
            })

        });
    });
}


</script>
</body>
  • 1
    The changes should be made in the backend to make the process easier for the frontend, so that you have to make only one call to get the results.. You are depending on the result of each `getJSON` call in the following call, so there is no way to make that process faster. – callback Apr 06 '18 at 16:26
  • 2
    You're probably looking for [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) – TLP Apr 06 '18 at 16:32
  • @ "callback" this is an API provided by NOAA / the National Weather Service, so I can't make any changes on the backend because I don't own the API. Maybe you meant something else, and I misinterpreted. BTW what's the difference between the answers that are here as opposed to the answers under "Answers" below (I'm new here, have mercy :) ) – Moonshot Apr 06 '18 at 18:07
  • Here are what are supposed to be comments, attempts to clarify what's meant, or tiny suggestions about where else to look. The answers below are actual attempts to answer your question. Please take the [tour](https://stackoverflow.com/tour) and check out the [help center](https://stackoverflow.com/help). – Scott Sauyet Apr 06 '18 at 18:47

2 Answers2

0

You can simplify quite a bit by using the then method of the Promises returned by $.getJSON:

const getStationFromLatLon = (lat, lng) => 
  $.getJSON('https://api.weather.gov/points/' + lat + "," + lng)
  .then(data => $.getJSON(data.properties.observationStations))
  .then(data => $.getJSON(data.observationStations[0]))
  .then(data => `${data.properties.name} ${data.properties.stationIdentifier}`)

getStationFromLatLon(39.7456, -97.0892)
  .then(console.log)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

You could also uses the standards-compliant fetch in place of jQuery's Ajax, with this simple wrapper:

const getJson = (url) => fetch(url).then(resp => resp.json());

This has no error-checking, but neither did the original. To be cleaner, you would need to check that the properties you're searching for are included in the returned data.

Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
  • Thanks Scott. Curious, why did you make the function "const"? – Moonshot Apr 06 '18 at 18:18
  • Because I would not expect it to change. I've been working in ES6 environments for some time, so that is my default. I don't use `var` at all, and only use `let` when necessary. – Scott Sauyet Apr 06 '18 at 18:45
-1

You will need to return a Promise and wait for the response. Try this:

var tLat = 40.985;
var tLon = -71.696;

function getStationFromLatLon(theLat, theLon) {
  return new Promise((resolve, reject) => {
    var theURL = "https://api.weather.gov/points/" + theLat + "," + theLon;
    var obsStationsURL;
    var obsStationURL;
    // This passes in the lat lons and gets the weather observation stations
    $.getJSON(theURL, function(data) {
      console.log(data);
      obsStationsURL = data.properties.observationStations;
      console.log(obsStationsURL);
      // Get the first obsStation using the obsStations URL
      $.getJSON(obsStationsURL, function(data2) {
        obsStationURL = data2.observationStations[0];
        console.log(obsStationURL);
        // Get the weather station ID and name using the station URL from previous call
        $.getJSON(obsStationURL, function(data3) {
          var stationID = data3.properties.stationIdentifier;
          var stationName = data3.properties.name;
          console.log(stationID + " " + stationName);
          var returnString = stationID + " " + stationName;
          resolve(returnString);
        });
      });
    });
  });
}

getStationFromLatLon(tLat, tLon).then(stationString => {
  console.log(stationString);
});
Pankaj Vishwani
  • 332
  • 1
  • 4
  • 9