0

So, I'm lost on how to handle this properly.

What I want to do is:

// client side
Meteor.call("getData", url, function(images) {
  console.log(images); // get array of image src
});

// server side
Meteor.methods({
  "getData": (url) => {
      var images = [];
     // here is where I am lost
     // scrape the images
     scrape.request(url, function(err, $) {
       if (!err) {
          $('img').each(function(img) {
            let src = img.attribs.src;
            images.push(src);
          }
          // so at this point, I can console log an array on the server, but I need to bring it back to the client
       }
     } // now, how do I push all these and then signal to return the array?
   return images; // returns undefined, not waiting for all the data
   // I'm not sure how to wait for the array to be updated.
}});

Thoughts?

So, recap, I want to get an array back of all the image sources scraped from the website passed to the Meteor method.

Daltron
  • 1,729
  • 3
  • 20
  • 37
  • 1
    Essentially a dupe of http://stackoverflow.com/questions/43404612/calling-a-function-in-meteor-method-returns-undefined/43404925#43404925 – Michel Floyd May 09 '17 at 05:54
  • @MichelFloyd If only! The problem is, the example you point to is essentially just returning a value from the callback of an async function. My example is not this straightforward because I am calling an async function from the client to the server, the server then makes an async call to a website and returns data AND then separates the data I need AND then I want to return the separated data. If you think otherwise, put your money where your code is and show me the answer :)! – Daltron May 09 '17 at 06:04
  • What about using `Promise` – Mostafiz Rahman May 09 '17 at 14:45

1 Answers1

2

There's a good tutorial on Meteor.wrapAsync that lays this out. Also this previous answer provides more details and explains error handling.

All the action happens on the server. In your case:

Meteor.methods({
  getData(url) => {
    const syncScrape = Meteor.wrapAsync(scrape.request);
    try {
      const $ = syncScrape(url,{});
      let images = [];
      $('img').each(img => {
        images.push(img.attribs.src);
      });
      return images;
    }
    catch(error) {
      throw new Meteor.error(error);
    }
  }
});

Also your client call needs to include an error from the callback:

Meteor.call("getData", url, (error, images) => {
  if (!error) console.log(images); // get array of image src
});
Community
  • 1
  • 1
Michel Floyd
  • 18,793
  • 4
  • 24
  • 39
  • Thanks for the answer. In the end, I couldn't get it working so I switched my scrapper to [scraperjs](https://www.npmjs.com/package/scraperjs) and used this answer to make that one work. Also, thanks for putting up with my sass! I was very tired and frustrated at that point. – Daltron May 09 '17 at 18:00
  • Glad you got it working. My Canadian spouse encourages me to help her compatriots ;) – Michel Floyd May 10 '17 at 00:10