0

Using the accuweather API I need to get the code of a city before getting the weather of that city. As the screenshot shows the location array is empty. The program still goes into the branch that expects an array that is not empty.

  router.get("/weather/currentweather/:location", async (req, res) => {
  try {
    const optionsForLocation = {
      uri: `http://dataservice.accuweather.com/locations/v1/cities/autocomplete?apikey=${config.get(
        "accuWeatherAPIKey"
      )}&q=${req.params.location}&language=en-us`,
      method: "GET",
      headers: { "user-agent": "node.js" }
    };
    rp(optionsForLocation, (error, response, body) => {
      if (error) {
        //console.error(error);
        //res.status(500).send("Server Error");
        res.json({ weather: "No Location found" });
      }
      console.log(response.body); // Returns []
      if (response.body === []) {
        //res.status(404).json({ msg: "No location found" });
        res.json({ weather: "No Location found" });
        //break;
      }
    }).then(function(locations) {
      console.log(locations); // Returns []

      if (locations === []) {
        res.json({ weather: "No Location found" });
      } else { // Still takes this path although locations === []
        const locationsJSON = JSON.parse(locations);
        console.log(locationsJSON);
        const key = locationsJSON[0].Key; //Always throws an error here as locationsJSON is empty if no location was found. This path should not be taken in the first place if locations === []

        const optionsForCurrentConditions = {
          uri: `http://dataservice.accuweather.com/currentconditions/v1/${key}?apikey=${config.get(
            "accuWeatherAPIKey"
          )}`,
          method: "GET",
          headers: { "user-agent": "node.js" }
        };
        request(optionsForCurrentConditions, (error, response, body) => {
          if (error) {
            console.error(error);
            res.status(500).send("Server Error");
          }
          if (response.statusCode !== 200) {
            return res.status(404).json({ msg: "No current conditions found" });
          }
          res.json(JSON.parse(body));
        });
      }
    });
  } catch (error) {
    console.error(err.message);
    res.status(500).send("Server Error");
  }
});

I fiddled with it for hours now, but can't get this error to get away.

Thanks for your help!

Till
  • 15
  • 2

1 Answers1

0

locations === [] will always be false. == and === with arrays checks to see if both sides refer to the same array, not equivalent arrays. Since the right-hand side of locations === [] is a newly-created array, the condition will always be false.

If you want to check for an empty array, check length:

if (locations.length === 0)

or

if (!locations.length)
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thanks for the reply! Checking for length still results in the same behaviour. The else-path is taken. – Till Sep 14 '20 at 08:04
  • @Till - Then either A) The array isn't empty as of the check, or B) (with apologies) you've checked incorrectly (did you forget the `!`?). – T.J. Crowder Sep 14 '20 at 08:07
  • I just did a few more console logs and it's really weird. clg(locations) -> returns [] clg(locations.length) -> returns 2 What? – Till Sep 14 '20 at 08:13
  • @Till - :-) That's [this surprising behavior](http://stackoverflow.com/questions/38660832/element-children-has-elements-but-returns-empty-htmlcollection). The array isn't empty. But if you do `console.log(locations)` the console gets a live reference to the array. If you expand that in the console, it expands with the array's contents **as they are then**, not as they were when you did the `console.log`. So the array has two entries as of that line, and something is removing them before you go look at it. – T.J. Crowder Sep 14 '20 at 08:17
  • This is one of the many reasons that rather than using `console.log`, you're best off using the debugger. Set a breakpoint on the `console.log(locations);` line, and when the breakpoint is reached you'll be able to see the two entries in the array. – T.J. Crowder Sep 14 '20 at 08:18