Question

I've been having a problem using an RSS parser in meteor. It's an async call, so it needs ot be wrapped, however it still doesn't seem to work. I presume this is because the anonymous on('readable' function is outside the fiber, but I can't see how to resolve it.

var FeedParser = Meteor.require('feedparser');
var request = Meteor.require('request');

function getBlog(url, parameter, id){

    request(parameter)
        .on('error', function (error) {
            console.error(error);
        })
        .pipe(new FeedParser())
        .on('error', function (error) {
            console.error(error);
        })

        .on('readable', function () {
            var stream = this,
                item;
            while (item = stream.read()) {
                Items.insert(new_item);                
            }
        });
    }

var wrappedGetBlog = Meteor._wrapAsync(getBlog);


Meteor.methods({
    blog: function (url, parameter, id) {
        console.log('parsing blog');
        var items = wrappedGetBlog(url, parameter, id);
    }
});
Was it helpful?

Solution

Meteor._wrapAsync() expects the wrapped function to return error and result to a callback. Your function, getBlog(), does not do that so _wrapAsync is not the right approach.

I have wrapped that function before but used a Future.

That approach allowed me to call feedparser from a Meteor.method(), which doesn't allow async functions, but you are also trying to do an insert inside the readable event. I think that insert will complain if it is not in a fiber. Maybe like this would also be necessary:

var r = request( parameter );
r.on( 'response' , function(){

  var fp = r.pipe( new FeedParser() );  //need feedparser object as variable to pass to bindEnvironment 

  fp.on('readable', Meteor.bindEnvironment( 
    function () {
      var stream = this,
        item;
      while (item = stream.read()) {         
        Items.insert(new_item);                
      }
    }
    , function( error ){ console.log( error );}
    , fp // variable applied as `this` inside call of first function 
  ));
});

Fibers is another option...

var Fiber = Npm.require( "fibers" );

 .on('readable', function () {
    var stream = this,
        item;
    while (item = stream.read()) {         
        Fiber( function(){
          Items.insert(new_item);
          Fiber.yield();
        }).run();                
    }
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top