1

In the code below, I try to return arr with details in it, but I think it's empty, because of the request. What can I do to make this work?

module.exports = function getWeather(country) {
  var arr = [];
  var pageToVisit = "https://www.timeanddate.com/weather/" + country;

  console.log("Visiting page " + pageToVisit);

  request(pageToVisit, function(error, response, body) {
    if (error) {
      console.log("Error: " + error);
    }
    
    // Check status code (200 is HTTP OK)
    console.log("Status code: " + response.statusCode);
    
    if (response.statusCode === 200) {
      // Parse the document body
      var $ = cheerio.load(body);
      
      console.log("Page title:  " + $('title').text());

      $('div.bk-focus__qlook').each(function(index) {
        var title = $(this).find('div.h2').text().trim();
        //var link = $(this).find('div.h1').attr('href');
        console.log('title: ' + title);
        //console.log(link);
        arr.push(title)
      });
    }
  });

  return arr;
}

The arr is always empty, and I can't add the title to the arr. How can I wait for it?

General Grievance
  • 4,555
  • 31
  • 31
  • 45
  • By using `async`/`await` or a `Promise`? – Mr. Polywhirl Sep 09 '21 at 14:55
  • Hi, duplicated question here: [How to return the response from an asynchronous call](https://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call) – ikhvjs Sep 09 '21 at 15:02

3 Answers3

0

I would write a function :

function pagetovisit( parameters if necessary) {
  // logic whatever you want to do
}




   async function asyncCall() {
/// stock the return value in a var 
      const result = await pagetovisit();
      console.log(result);
      // expected output: "resolved"
    }
Dezz H
  • 322
  • 6
  • 23
0

It does not look like that website uses a public-facing weather API. Looks like an pre-rendered HTML page that loads from the server.

The API information does even include weather: https://www.timeanddate.com/services/api/

If you were to return a list of scraped text, you would need to make your function a asynchronous and return the Promise like so:

const parseHTML = (htmlText) =>
  new DOMParser().parseFromString(html, 'text/html');

const getWeather = async (country, city) {
  var pageToVisit = `https://www.timeanddate.com/weather/${country}/${city}`

  console.log(`Visiting page: ${pageToVisit}`);

  return fetch(pageToVisit, {
    method: 'GET',
    headers: {
      'Content-Type': 'text/html',
    }
  })
    .then(response => response.text())
    .then(parseHTML)
    .then(doc =>
        [...doc.querySelectorAll('div.bk-focus__qlook')].map(qlook =>
          qlook.querySelector('div.h2').textContent.trim()));
};

module.exports = getWeather;

// https://www.timeanddate.com/weather/usa/chicago
const weather = await getWeather('usa', 'chicago'); // Should not be empty

I would ditch this website, because:

  1. Scraping is inefficient
  2. There are better (and free) weather APIs out there
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
0

thank you all, I use callback fun and it work.

var cheerio = require('cheerio');
var URL = require('url-parse');
var express = require('express');


var country="canada";


module.exports= function getWeather(country,callback){

  var arr=[];
  arr.push(country)
  
  var pageToVisit = "https://www.timeanddate.com/weather/"+country;
  console.log("Visiting page " + pageToVisit);
  
  
   request(pageToVisit, function(error, response, body) {
     if(error) {
      callback(error);
       
     }
     // Check status code (200 is HTTP OK)
     console.log("Status code: " + response.statusCode);
     if(response.statusCode === 200) {
       // Parse the document body
       var $ = cheerio.load(body);
       console.log("Page title:  " + $('title').text());
  
      
       $('div.bk-focus__qlook').each(function( index ) {
          var temp = $(this).find('div.h2').text().trim();
          var wind = $(this).find('p').text().trim();
          var index=wind.search("Wind")
          wind=wind.substring(index);
          arr.push(temp)
          arr.push(wind)
          
          });    
        
     }
     callback(null, arr);
      
  
  });
  
  }
  
   getWeather(country, function(err, result){ 
        if(err) {console.log(err); }
        else {
            console.log(result);
           
        }
   });