A simple RSS reader in NativeScript

This post is more than 2 years old.

Last week I wrote up my initial thoughts on working with NativeScript. After working through the getting started guide, I thought I'd take a stab at building a simple app, a RSS reader. Before going further, note that you should assume my code is crap. It works - but I'm sure I've done things like - well - a noob. Because I am. So I'd think twice before using my code. (Although you are welcome to it - I'll have a link to the code at the end.)

My RSS reader consists of two screens - an initial list based on the entries from an RSS feed and a detail page for the actual blog entry. Here's the initial screen.

Screen shot 1

To be clear, that lovely red header there was me using my design chops. Don't blame NativeScript for that. Anyway, here's the detail view:

Screen shot 2

That's a lot of text (partially because that blog entry really does have a lot of text at first) and not terribly nice looking, but it works. Now let's take a look at the code.

First off, the home page view, which is really just a list.

<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="loaded">

		<ActionBar title="{{ title }}" />

	<StackLayout orientation="vertical">
		<ListView items="{{ rssList.feedItems }}" itemTap="loadItem">
				<Label text="{{ title }}" horizontalAlignment="left" verticalAlignment="center" />

Nothing too special here. You've got a list with a tap handler. On top you can see a call to loaded() for when the page loads. Now let's look at the code behind this.

var RssListViewModel = require('../shared/view-models/rss-list-view-model');
var frameModule = require('ui/frame');

var config = require('../shared/config');

var Observable = require('data/observable').Observable;
var viewModule = require('ui/core/view');
var page;

var pageData = new Observable({

exports.loaded = function(args) {
	page = args.object;
	page.bindingContext = pageData;

exports.loadItem = function(args) {
	console.log('tap item',args.index);
	console.log('tap item 2', args.view.bindingContext.title);
	//rssList.viewModel.set('selectedItem', args.view.bindingContext);
	RssListViewModel.viewModel.set('selectedItem', args.view.bindingContext);

So for the most part, this too is rather simple. Most of the logic is in a view module. This file basically handles asking the view model to do it's thing and return a list of RSS entries.

I do want to point out one thing. Notice in loadItem() I call a set operation. This is how I handle "I'm leaving this view but want to remember what I clicked." This one thing took me roughly 70% of the development time for this project. Why? At first, I was creating an instance of my view model, not just requiring it. I did this on my detail page too. That meant when I set a value on it on the list page, I lost that when the object was recreated on the detail page. That seems trivial, but it took me forever to get around that.

I also discovered later that you can pass random data to another view via navigate. You can see that described here in the docs. I didn't see that at first because when I went to the API reference in the docs, I was initially on the "Module" for Frame and not the "Class" for it. I honestly don't know the difference (I just asked on Slack though so hopefully I'll get a clue ;).

Now let's look at the detail page.

<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="loaded">

		<ActionBar title="{{ title }}" />

	<StackLayout orientation="vertical">
			<HtmlView html="{{ text }}" />

Again - fairly simple. I first used a TextView and of course that doesn't render HTML. I did find odd performance issues with this control. The first few views worked perfect. Then I saw a noticeable lag in rendering the view. I'd say maybe 2-3 seconds. I'm fairly certain it is probably my code, but I've let me friends on the NativeScript code know about what I encountered. Ok, so now the code behind the view.

var RssListViewModel = require('../shared/view-models/rss-list-view-model');
var Observable = require('data/observable').Observable;

var pageData = new Observable({

exports.loaded = function(args) {

	page = args.object;
	page.bindingContext = pageData;
	console.log('loaded the item page');
	pageData.title = RssListViewModel.viewModel.get('selectedItem').title;
	pageData.text = RssListViewModel.viewModel.get('selectedItem').description;


Basically I ask for the data I saved in the previous view and update a local observable. I had tried to bind directly to my instance of RssListViewModel, but noticed that content only updated one time. Again - that's possibly my fault.

Finally, let's look at the view model. I used one of the methods I described in my blog post on the topic - Parsing RSS Feeds in JavaScript - Options. Just in case it isn't obvious - yes - I used something in NativeScript that worked perfectly fine for Cordova too. While I may struggle a bit with the UI of NativeScript and other aspects, being able to re-use stuff I've already learned in the hybrid space is a big win. Anyway, the code:

var observable = require('data/observable');
var ObservableArray = require('data/observable-array').ObservableArray;
var fetchModule = require('fetch');
var config = require('../config');

function handleErrors(response) {
	if (!response.ok) {
		throw Error(response.statusText);
	return response;

exports.empty = function() {
	while (feedItems.length) {

exports.load = function name(params) {
	console.log('CALLING LOAD');
	//handle caching
	if(feedItems.length > 0) {
		console.log('leaving early');

	return fetch('https://query.yahooapis.com/v1/public/yql?q=select%20title%2Clink%2Cdescription%20from%20rss%20where%20url%3D%22'+encodeURIComponent(config.rssURL)+'%22&format=json&diagnostics=true', {
	.then(function(response) {
		return response.json();
	}).then(function(data) {
		console.log('number of rss entries: '+data.query.results.item.length);
		data.query.results.item.forEach(function(feedItem) {
						title: feedItem.title,
						link: feedItem.link,
						description: feedItem.description


var feedItems = new ObservableArray();
exports.feedItems = feedItems;

var viewModel = new observable.Observable();
exports.viewModel = viewModel;

This is - I assume - mostly self-explanatory, but let me know in the comments below if anything isn't clear. There's one more file I didn't show yet - a simple config object I can use to quickly change the title of the app and the RSS feed:

module.exports = {
	title:"Raymond Camden's Blog"

There's two things missing from this app that I'd like to correct. First, a good mobile application should recognize when it is offline. I need to update the app to notice that, let the user know, and possibly start working again once network connectivity is restored. Secondly, many RSS feeds only contain a small portion of the entry text. I'd like to add a button that would open the entry in the native browser for proper reading.

Want the complete code? (And again, remember that it is code being written by a noob. I'd hate to be accused of leading people to bad code.) You can find the complete source here: https://github.com/cfjedimaster/NativeScriptDemos/tree/master/rssTest1.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Shironsh Ajento posted on 10/24/2016 at 6:09 AM

Hello Raymond,

I'm just starting with NativeScript

On my own, i've manged to fetch a json feed, parse it and show it on a listview,
but i'm bit stuck on using the same view for both list and article view

( right now, whenever i comeback from a article, it loads the whole list all over )
so how can i use the same view like you're doing it here

I've downloaded your sample too, but still didn't get that part :/

Comment 2 (In reply to #1) by Raymond Camden posted on 10/24/2016 at 1:54 PM

I'm not quite sure I get what you mean. I'm not using the same view, I'm using two views. One for the list, one for the entry.

Comment 3 (In reply to #2) by Shironsh Ajento posted on 10/28/2016 at 6:09 AM

Hey, Thanks for the reply

Basically, i can't figure out how you're only loading data once ( in the main listview ), and when you come back from the detail view, that loaded data is still there, that's the part where i'm stuck with.

this is my app directory - https://drive.google.com/fi...

The only solution i could figure out was saving the data on a local text file and reload it when coming back from the detail view, but i'm not sure how well it'll work with lot of entries.

Comment 4 (In reply to #3) by Raymond Camden posted on 10/28/2016 at 7:05 PM

I use the loaded() event, which is fired once, and the result is bound to the page, so it only needs to load once.

Comment 5 (In reply to #4) by Shironsh Ajento posted on 10/31/2016 at 12:35 PM

Same here, but it's still happening.

I just finished a tute from Uppsala.js, they're developing on OSX for iOS, i'm on Windows emulating for Android, on their screencap it doesn't seem like loading twice ( maybe it does, but they're not firing any alerts or anything to check )

anyhow i manged to kinda fix it.

It still does re-fetch data if coming back from recent screen of android, but doesn't loose data, so i guess i'll just catch() errors on http module with network status.

Thank you for all your articles and help, i've been reading this for a while ( for Cordova and everything )