How to read RSS feeds into Meteor?


#1

I’ve been banging my head against the wall trying these packages:

  • danielqiu:feed
  • hoangdo94:scrape
  • peter:rss

I’m trying to read from the following feed:
http://www.ndbc.noaa.gov/rss/ndbc_obs_search.php?lat=40N&lon=73W&radius=100

The closest I got was using the feed package, but ended up w/this error:
Exception: MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key error index: meteor.feed_entries.$_id_ dup key: { : "http://www.ndbc.noaa.gov/" }
I was going to fork the package but wanted to see if there was a better method.

Anyone have any luck w/reading rss & meteor, help is appreciated!


#2

Why not just go with something like https://www.npmjs.com/package/feedparser?


#3

Thanks @vigorwebsolutions! This looks very promising! Any examples or hints on pushing a feed up to a meteor subscription?


#4

That is a tough one that depends on your use case and how involved you want to get. The simplest thing would be to call a method that retrieves the feed and returns it in a way that you can pass to an #each. With more time/resources, I’d think about the following:

If you are seeing a lot of re-use of feeds, I’d probably cache the rss content to a collection.

If you need the functionality of a pub/sub but don’t want to persist the data, you can use a low-level publication, but be warned that they can be tricky to maintain in comparison to the super easy-to-use default pub/sub architecture.

If I were you, I’d probably start with an onCreated/event to call your rss method, and store the results as a reactiveVar tied to the template. Then pass that var into an #each and you have reactive data without too much overhead.


#5

I’m using parse-feed to parse an RSS feed on the server side and that works well. However, being quite new to Meteor and Javascript in general, I can’t figure out how to display the feed in the client.

What I’m trying to accomplish is to display my latest blog posts from Medium on my personal website (under development). It would be easy with a normal pub/sub, but I don’t want to insert the posts to Mongo since they won’t be needed when newer posts come and replace them. This wouldn’t be a problem since the overall number of posts won’t ever be huge, but there has to be another way.

What I’ve tried is having a server side method that fetches and parses the feed:

fetchLatestBlogposts() {
    let feed = require("feed-read");
    let url = "https://www.medium.com/feed/[myusernamehere]";
    let firstPosts = [];

    feed(url, function(err, posts) {
        if (err) {
            console.log("There has been an error: " + err);
        }

        for(let i = 0; i < 2; i++) {
            firstPosts.push({
                "title": posts[i].title,
                "content": posts[i].content,
                "published": posts[i].published,
                "link": posts[i].link
            });
        }
        console.log("hello from server" +firstPosts);
        return firstPosts;
    });
}

This method successfully fetches the blogposts and inserts them to the array (which the server side console.log proves) I would like to return. I can’t however get them through to the client.

My client side looks somewhat like this. I’m using React as the UI component, so there are eg no Blaze templates.

posts() {
    Meteor.call("fetchLatestBlogposts", function(err, result) {
        if (err) {
            console.log("error in client: " + err);
        }
        if (result) {
            return result;
        }
        console.log("no result found");
    });
}


render() {
    return(
        <div className="blog-latest">
            <div className="blog-latest-text">
                //irrelevant code until next line
                {console.log("UI " + this.posts())}
            </div>
        </div>
    )
}

The client logs “UI undefined” (from render()) and “no results found” (from posts()) respectively. However it triggers the server side method, which logs what it’s supposed to log to the server console. So it seems apparent that the render() finishes before posts(), but I can’t figure out why posts() doesn’t get any result from the callback.

I suppose my problem is rather with not understanding the asynchronous way that Javascript works than with Meteor, but any help is greatly appreciated.