My first AngularJS web app, part 2

Picking up from my previous installment, I created my web app layout and styling using Bootstrap, heavily customized so it doesn’t look like the standard Bootstrap-built site. Now it’s time to start hanging the meat on the bones by integrating AngularJS and JavaScript. Note that in this and subsequent blog posts I will discuss the high-level design of the app rather than reviewing individual code snippets. Frankly, assuming you can code, I believe it’s more important to understand the design reasoning and notable learnings rather than wading through code to demonstrate syntax.

As you can see on Minecraft Free News, there are essentially two major areas on the page: the feed selection at the very top of the page, and the content (individual feed items) displayed on the rest of the page. After creating the AngularJS module, I created two AngularJS controllers: FeedController to manage the feed source selections at the top, and ContentController to manage populating the feed items into the content area. I created an Angular service that simply provides a data object containing an array of all feed sources including the title, URL, whether the feed is enabled or disabled, and the maximum number of feed items to pull. Via this service, the data object is shared between the FeedController and ContentController. When the user clicks on a feed source to toggle its enable/disable attribute, the specific feed in the data object is changed by the FeedController, and that information is provided to the ContentController which immediately acts upon it to show or hide that feed’s items in the content area. In other words, this service serves as a communication conduit between my two controllers.

I created another Angular service called PullFeeds to interface with Google’s Feed API to pull each individual feed’s content items. This object relies upon Angular promises, an entity bundled with Angular to support asynchronous interactions. As our app is sourcing RSS data from other websites, we are at the mercy of the network and server delays. Per the Google Feed API, we can make a call to pull the feed items from a specific feed URL, and we must supply a call-back function that will process the items received from that feed. Without using a promise, when the PullFeeds service is executed, it will return immediately without any feed items because the action via Google’s Feed API is asynchronous and thus not yet completed. However, when using a promise in the service, only when our call-back function receives the data will the promise be fulfilled and data returned from the service as desired.

I also use promises elsewhere in the app (via another custom service) to pull JSON data from my own server in order to insert custom ads and news items inline in the content. Beyond returning data, promises can also return a rejection that indicates the deferred action failed (i.e. a failed promise to deliver). In my case, if the promise to read the data from my server failed (e.g. the server is down, network inaccessible, etc.), our web app can handle it gracefully by receiving the rejected promise and displaying the feed items without ads.

As a final note for this installment, I want to point out that all of the Javascript execution described thus far occurs on the client side. The HTML, CSS, and Javascript are read by the client from my server, and using AngularJS the resulting page is rendered entirely by the client. All of the feed items are pulled by the client. My server is only used to serve the relatively small HTML/CSS/Javascript, and to supply a small JSON object for custom ad and news items. Though seen as a dynamic web app from the client side, from the server’s perspective it’s all static content and thus very little bandwidth is required.

My first AngularJS web app, part 1

As I mentioned in a previous blog post, I spent the past three months traversing the ecosystem of JavaScript and Node, attempting to learn the language that once mystified me. Along my journey I discovered various MVC frameworks designed to streamline web app development, and I gravitated to AngularJS. As with any programming endeavor, one can only read so much before the call of the command line beckons you to write a real application using everything just learned.

My son, like every other kid in America, is currently a Minecraft fanatic. When he’s not actually playing Minecraft, he is hopping from website to website reading news about the game and watching screencasts from other prominent Minecraft gamers. After some discussion with my son, I decided to built my first web app to aggregate all of the news and video links from the Minecraft websites he likes into a single one-page resource. First, here is the app (using a domain name that was surprisingly available):

In a nutshell, it’s an RSS reader app that pulls feeds from specific feed sources (annotated at the top), sorting and displaying all the articles in reverse chronological order. Any feed source can be enabled or disabled, and that setting is remembered by the browser. The client’s browser, not the web server, pulls all the articles from the selected RSS feeds after the page is loaded. There is an optional top-line article section and ads displayed inline in the content, both of which are pulled from my web server. More on that later.

From a visual design standpoint, you might notice it’s modeled after the styling of DrudgeReport — a site that may look like a 1990’s relic, but in fact accomplishes its goal of delivering links to current news stories with sheer simplicity and readability (read more). I started with Bootstrap and made some modifications via its LESS variables to attain the layout styling I desired. Using Harp as a local web server on my laptop, I included the Bootstrap LESS file and added my own custom LESS file to override specific Bootstrap variables. Harp then automatically compiled the Bootstrap LESS files and my custom LESS file as CSS for each page reload from the Harp web server so I could tweak and view the changes in real time. Once I was satisfied, I saved the resulting Bootstrap CSS to a text file, and that became my Bootstrap CSS for the project. For such a simple design style, using Bootstrap is arguably overkill; however, Bootstrap bought me responsiveness to all types of devices, from laptops to phones, out of the box.

Look for the next installment to learn how I developed the app.

Using Harp for Web Development

While meandering around the web and perusing for JavaScript and AngularJS guides and tutorials, I stumbled upon a brilliant tool that has served as my local development web server and more. It’s called Harp, and per the instructions on its webpage, it’s installed through npm.

Harp describes itself as a “new kind of static web server that has built-in preprocessing”. At the most basic level, it enables me to quickly start a web server locally on my laptop (on any port) and have it serve the files from any directory structure of my choosing. By simply entering “harp server” from the command line while in directory I wish to be served, I can then point my browser to http://localhost:9000 to render the site using the HTML, CSS, and JavaScript in that directory tree. This means if you’re developing a basic webpage in HTML and CSS, or building a more complicated web app using JavaScript and AngularJS, Harp serves it all cleanly.

If you’re a fan of Bootstrap like me, you know that Bootstrap is actually developed using LESS, and is then compiled down to CSS. If you want to make changes to Bootstrap, it’s easiest to tweak the pre-compiled LESS files so your changes are propagated correctly into the resulting CSS. Harp is quite intelligent, and will automatically render LESS files into CSS on the fly. This means that while running Harp as a web server, your HTML pages can link in Bootstrap’s LESS files as CSS without having to manually compile the LESS files; Harp handles it. Check out the video tutorial (especially around 6:53) to see how Harp works with Bootstrap. Again, it’s absolutely brilliant, and a big timesaver when you want to customize the LESS variables for Bootstrap for your particular site.