• Home
  • About
  • Contact
Brandon Tillman

AngularJs Tutorial: WoW Realm Status

January 27, 2016 by Brandon Leave a Comment

Intro

This tutorial will show you an example app I wrote in AngularJs for the popular video game World of Warcraft.  It will show you how to create simple http requests against Blizzard’s API, you’ll need to register for an API key there if you plan on running this app. It will then demonstrate how to take that data, and populate an html table, which we will also build sorting and filtering into.

WoWRealmStatus

This project is free and open source, it can be found on GitHub.

A demo of it working live can be found here.

Prerequisites

To start this application off, we will need to create a web directory with three folders in it (css, js, fonts), that we will later populate with our code, for our web server to send up to the clients browser. Inside the js directory, we’re making two new folders, home and libs to organize things a bit. Home will contain all the controllers and views that are related to the home view, any other views added later will have their own directory. Libs contains our JavaScript libraries as you may have guessed.

List of 3rd party libraries used:

  • Bootstrap 3 (any theme).
  • Font Awesome 4.
  • UI Bootstrap directives.

Getting started

Lets go ahead and start creating some JavaScript, create the file app.js inside the js directory, which will contain our AngularJs module to bind everything together.

(function () {
    'use strict';
    angular.module("RealmStatus", ['ui.bootstrap']);
})();

Notice we’ve added in our ui.bootstrap module, this allows us to implement their code throughout the rest of our application module.

AngularJs Factory

The AngularJs factory is responsible for creating http requests against the Blizzard API to retrieve the data, in this case a list of World of Warcraft realms. If you haven’t received an API Key yet, now is the time. Create the app.factory.js file and change apiKey to your own.

(function () {
    'use strict';
    angular
        .module("RealmStatus")
        .factory("RealmService", RealmService);

    // Minification friendly dependency injection
    RealmService.$inject = ['$http'];

    function RealmService($http) {
        // Should really be in config somewhere outside factory
        var endpoint = "https://us.api.battle.net/wow/realm/status?";
        var locale = "locale=en_US";
        var apiKey = "&apikey=YOUR KEY HERE";
        var jsonp = "&jsonp=JSON_CALLBACK";

        return {
            // Public API's
            getRealms: _getRealms
        }

        function _getRealms() {
            return $http.jsonp(endpoint + locale + apiKey + jsonp)
                .then(getRealmsComplete)
                .catch(getRealmsFailed);

            function getRealmsComplete(response) {
                return response.data;
            };

            function getRealmsFailed(error) {
                console.log(error)
            };
        };
    }; 

})();

The factory is pretty simple, it builds a url using a “config”, makes the http request, handles the success and failure, and returns data. We will use this in our AngularJs controller to retrieve the data when requested.

AngularJs Controller

Our controller is going to handle the user interaction, and use the factory to retrieve the data for display using HTML directives. Create the home.controller.js file in js/home.

(function () {
    'use strict';
    angular
        .module("RealmStatus")
        .controller("HomeCtrl", HomeCtrl);

    // Minification friendly dependency injection
    HomeCtrl.$inject = ['RealmService'];

    function HomeCtrl(RealmService) {
        var vm = this;
        // Holds data object
        vm.realms;

        // Table sorting defaults
        vm.sortType = 'name';
        vm.sortReverse = false;
        vm.searchRealm = '';

        // Call our realm service factory on-load, to get the data
        RealmService.getRealms()
            .then(function (data) {
                // Assign realms to the data from the webservice
                vm.realms = data.realms;
            });

    };

})();

As you can see, we $injected the RealmService (our AngularJs Factory) into our controller, and used the .getRealms() method to return our promise chain with some data. We also have some defaults specified for our table sorting filters, that we’re going to add in the html later.

AngularJs Filters

This file defines filters that we can use in our HTML to morph the output of certain data. Create app.filters.js.

(function () {
    'use strict';
    angular
        .module("RealmStatus")

        // Capitalizes words
        .filter('capitalize', function () {
            return function (input) {
                return (!!input) ? input.charAt(0).toUpperCase() + input.substr(1).toLowerCase() : '';
            }
        })
        // Fixes the formatting of our realm list
        .filter('realmlist', function () {
            return function (array) {
                var fixed = [];
                array.forEach(function (item) {
                    item = item.replace(/-/g, " ");
                    item = item.charAt(0).toUpperCase() + item.substr(1).toLowerCase();
                    fixed.push(item);
                });
                return fixed.join(", ");
            }
        }); 

})();

We will use these filters in our HTML file below.

Index.html

The index.html contains references to all our AngularJs scripts, as well as inline attributes to let AngularJs do its magic. I will try to highlight only the important parts for brevity.

<body ng-app="RealmStatus"></body>

This line is important, it lets AngularJs know that everything within it is part of the app. Next, lets declare our controller, like the ng-app directive, ng-controller assigns everything within the div to itself.



<div ng-controller="HomeCtrl as vm"></div>



We used ng-model to create a variable in page scope to hold our table filter input “searchRealm”. This is where the user will type in what they’re filtering for in the table search input.

<!-- Filter input box -->
<input type="text" class="form-control" placeholder="Filter..." ng-model="searchRealm" />

To make the table headers clickable, and modify the table filter, we added the ng-click mechanism below to each header, replacing vm.sortType with the appropriate type.

<!-- Table headers with sorting -->


<th ng-click="vm.sortType='name'; vm.sortReverse = !vm.sortReverse">
    Name
    <span ng-show="vm.sortType == 'name' && !vm.sortReverse" class="fa fa-caret-down"></span>
    <span ng-show="vm.sortType == 'name' && vm.sortReverse" class="fa fa-caret-up"></span>
</th>


Then, in our table data rows, we filtered the data inside ng-repeat using the filters in the controller. These are changed by clicking the table headers, and the DOM is updated on the fly (thank you AngularJs!).

<!-- NgRepeat to display each realm per row sorting is applied here too -->

<tr ng-repeat="realm in vm.realms |orderBy:vm.sortType:vm.sortReverse | filter:searchRealm">
    <td>
        <span class="status-{{realm.status}}" uib-popover={{realm.connected_realms|realmlist}} popover-title="Connected Realms" popover-trigger="mouseenter">
            {{realm.name}}
        </span>
    </td>
    <td>
        <span class="pop-{{realm.population}}">
            {{realm.population | capitalize}}
        </span>
    </td>
    <td>
        <span>
            {{realm.battlegroup}}
        </span>
    </td>
    <td>
        {{realm.timezone}}
    </td>
</tr>

Also, notice the app.filters we created earlier being used here. This is what generates our table, and populates it with data.

That’s all there is to it, a nice, clean and simple web application in AngularJs. Please check out GitHub for a full view of the code, it may answer any questions you have, if not feel free to comment below and I will happily respond. Thank you for reading!

  • Author
  • Recent Posts
Brandon
Sr. Software Engineer at Undisclosed Investment firm/Brokerage
Latest posts by Brandon (see all)
  • RadListView | Using the Telerik UI for Xamarin.Forms - August 6, 2019
  • Clean Architecture | Creating Maintainable Software using .NET Core - May 2, 2019
  • Xamarin Forms How-to: Navigation with slide out menu - August 15, 2017

Share this:

  • Click to share on Twitter (Opens in new window)
  • Click to share on Facebook (Opens in new window)
  • Click to share on LinkedIn (Opens in new window)
  • Click to share on Reddit (Opens in new window)
  • Click to share on Pinterest (Opens in new window)
  • Click to email a link to a friend (Opens in new window)
  • Click to print (Opens in new window)

Like this:

Like Loading...

Related

Posted in: AngularJs, Featured, Javascript, Projects Tagged: AngularJS, Blizzard API, HTML5
← Entity Framework Code-First tutorial | C# .NET MVC 5
Callbacks | Understanding JavaScript flow →

  • Popular
  • Latest
  • Today Week Month All
  • Xamarin Forms How-to: Navigation with slide out menu Xamarin Forms How-to: Navigation with slide out menu (14,759 views)
  • Clean Architecture | Creating Maintainable Software using .NET Core Clean Architecture | Creating Maintainable Software using .NET Core (4,810 views)
  • How to: Create custom code snippets in Visual Studio Code How to: Create custom code snippets in Visual Studio Code (2,123 views)
  • AngularJs Tutorial: WoW Realm Status AngularJs Tutorial: WoW Realm Status (1,374 view)
  • Entity Framework Code-First tutorial | C# .NET MVC 5 Entity Framework Code-First tutorial | C# .NET MVC 5 (1,032 view)
  • RadListView | Using the Telerik UI for Xamarin.Forms RadListView | Using the Telerik UI for Xamarin.Forms
  • Clean Architecture | Creating Maintainable Software using .NET Core Clean Architecture | Creating Maintainable Software using .NET Core
  • Xamarin Forms How-to: Navigation with slide out menu Xamarin Forms How-to: Navigation with slide out menu
  • How to: Create custom code snippets in Visual Studio Code How to: Create custom code snippets in Visual Studio Code
  • password ASP.NET Core Identity | Change default password restrictions
Ajax spinner

Beer me!

Did one of my posts help you out? I'm glad! If you'd like to help supply my fuel for more posts - please consider donating to the cause!

10-Day Free Trial

Tags

.net .Net Core AngularJS API Architecture Authentication Blizzard API Callbacks CentOS code first commanline entity framework HTML5 http JavaScript linux minecraft Networking restful srv Telerik Template Tutorial UI vm VSCode Web web api web development Webservice wordpress Xamarin XAML

Recent Comments

  • Tillman32 on Xamarin Forms How-to: Navigation with slide out menu
  • hartman on Xamarin Forms How-to: Navigation with slide out menu
  • Tillman32 on Xamarin Forms How-to: Navigation with slide out menu
  • hartman on Xamarin Forms How-to: Navigation with slide out menu

Categories

  • .Net
  • AngularJs
  • Entity Framework
  • Featured
  • Javascript
  • Linux
  • Minecraft
  • Projects
  • Tutorial
  • Videos
  • Wordpress
  • Xamarin

Follow me on Twitter

My Tweets

Copyright © 2023 Brandon Tillman.

Omega WordPress Theme by ThemeHall

%d bloggers like this: