AngularJS and ASP.net Core 1.0 JumpStart (Part – I)

Building the “Answer It!” app

“Answer It!” is an app more like the famous TV show “Who wants to be a millionaire” but a bit different. Here a user will be presented with some predefined question sets. User will have to answer all the questions in limited amount of time and grab the glorious prize of “NOTHING”. I’ll build the app from scratch following some patterns and practices in both server and client side. In the end of this series you will have a good understanding on how to build Angular apps quickly and efficiently. So get a cup of coffee and let’s begin.

Libraries, we are using when building the client

In this part we are going to build the client side only. In client side I’m using,

  • Bootstrap – A free library for giving your app a nice look and feel on the fly
  • AngularJS – A very famous javascript library for building client side application
  • Angular UI Router - A third party library for making angular ui routing easier

Brackets – An absolutely amazing Text Editor

N.B: I’m using Brackets as my Text Editor because it has a built in live previewer, which basically build a node server internally for serve up your web pages and other assets. It helps me not thinking about building a server when I’m only doing client side works.

Downloading and Setting up everything

You can download Bootstrap and AngularJS separately from their official sites or you can use CDN (content delivery network) links. Both are fine, choose any! Here is the CDN link for downloading the CSS library of bootstrap.

https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css

I’m only using the CSS library since I won’t use any of the javascript components like carousel, accordion which ships with bootstrap.js. It also saves me from referencing JQuery in my project since bootstrap.js needs JQuery. But if you want them, here are the links,

JQuery - https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js

Bootstrap JS library - https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.min.js

N.B: You can browse and get CDN links for other javascript libraries from https://cdnjs.com/

Now create a folder anywhere you like, name the folder “Answer It” and open it in Brackets, (File -> Open Folder…) (Ctrl + Alt + O)

Don’t worry if your Brackets interface doesn’t look like mine. I’m only using some extensions nothing more.

Now, File -> New (Ctrl + N) and save as (Ctrl + S) index.html. Copy and paste the markup given below,


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" media="screen" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css">
    <title>Answer It!</title>
    <!--  -->
    <style></style>
</head>
<body>
    <script></script>
</body>
</html>

You can run your app and view it in the browser right now just by clicking on the thunderbolt icon from the right side menu. This is the Brackets build in live previewer that I was talking about. At this moment you will see nothing but a blank page. Let’s spice up the look and feel of the app. Bootstrap community provides a bunch of ready to use templates which are free of cost. Here is link to find all sorts of free templates provided by bootstrap,

http://getbootstrap.com/getting-started/#examples

I’m using the Cover template.

http://getbootstrap.com/examples/cover/

To be able to use a template just click on the thumbnail and on the template page right click on the browser window and select “View Page Source”cover.css (look for it in the head section) file and save it in your project folder.

http://getbootstrap.com/examples/cover/cover.css.

Now copy the markup under the <body> tag and paste it down in your index.html file’s <body> tag.

Last of all add a reference to the downloaded cover.css file in the head section. If you run your app now. You will get the exact look of the Bootstrap cover template. I’ve changed the title and some link text. Here goes the final markup of the index.html and the look of the running app,


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" media="screen" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css">
    <link rel="stylesheet" media="screen" href="cover.css">
    <title>Answer It!</title>
</head>
<body>
    <div class="site-wrapper">
        <div class="site-wrapper-inner">
            <div class="cover-container">
                <div class="masthead clearfix">
                    <div class="inner">
                        <h3 class="masthead-brand">Answer It!</h3>
                        <nav>
                            <ul class="nav masthead-nav">
                                <li class="active"><a href="#">Play</a></li>
                                <li><a href="#">How To</a></li>
                                <li><a href="#">About</a></li>
                            </ul>
                        </nav>
                    </div>
                </div>
                <div class="inner cover">
                    <h1 class="cover-heading">Welcome to Angular and ASP.net Core 1.0 JumpStart</h1>
                    <p class="lead">This inner section will be replaced by partial views</p>
                </div>
                <div class="mastfoot">
                    <div class="inner">
                        <p>Answer It!, by <a href="https://twitter.com/@FiyazBinHasan">@FiyazBinHasan</a>.</p>
                    </div>
                </div>
            </div>
        </div>
        <script></script>
</body>
</html>

Adding Angular.js and UI Router

At the very bottom of the <body> tag add the library for Angular.js and Angular UI Router. Here are the CDN links for them,

https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js

https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.min.js

I could have used Angular’s built in route service (ngRoute). But Angular UI Router make things easier.

Creating the main app module

To create the main module for the app, create a file called app.module.js under your project folder and add the scripts below,


(function () {
    'use strict';

    angular.module('answerit', [
        'ui.router'
    ]);
})();

I named the module answerit and in the third braces I’m adding the Angular UI Router dependency (ui.router). You can add other dependencies here if you want. Like UI router there are many third party angular modules available. Let’s do the routing, since I’ve three navigation links namely (Play, How To and Contact), Ill configure three routes for them using UI router, here is the code for configuring the routes,


(function () {
    'use strict';

    angular.module('answerit', [
        'ui.router'
    ]).config(['$urlRouterProvider', '$stateProvider', configRoutes]);

    function configRoutes($urlRouterProvider, $stateProvider) {
        $urlRouterProvider.otherwise('/play');

        $stateProvider
            .state('play', {
                url: '/play'
            })
            .state('howto', {
                url: '/howto'
            })
            .state('about', {
                url: '/about'
            });
    }
})();

So we have three routes each of which will trigger if a user types the routing URL in browser’s address bar (example: http://#/play). $urlRouterProvide.otherwise("/play") is responsible for taking you back to the /play route if user’s entered URL doesn’t fall into the configured route list.

Routing won’t work until we refer the module name in our html file. So, go to index.html, first add the reference to the app.module.js script at the bottom of the <body> tag after the angular.js and angular.ui.router.js reference scripts tags. After that add ng-app="answerit" attribute in the <html> tag. Here ng-app is an angular directive. If you try to view your app now. You will have an empty cover template since we didn’t attach any view with the respective routes.

I’ve created three blank html files (play.html, howto.html, about.html). It’s getting messy already with all the files in the root folder. Let’s do some folder structuring. Add a folder named css and move the cover.css into it. Add a folder named js. Under that add another folder named app and move the app.module.js file into it. Last of all add a folder named templates and move those three newly created html files into it.

Now go to your app.module.js and add the three views with their respective routes using templateUrl property.


(function () {
    'use strict';

    angular.module('answerit', [
        'ui.router'
    ]).config(['$urlRouterProvider', '$stateProvider', configRoutes]);

    function configRoutes($urlRouterProvider, $stateProvider) {
        $urlRouterProvider.otherwise('/play');

        $stateProvider
            .state('play', {
                url: '/play',
                templateUrl: 'templates/play.html'
            })
            .state('howto', {
                url: '/howto',
                templateUrl: 'templates/howto.html'
            })
            .state('about', {
                url: '/about',
                templateUrl: 'templates/about.html'
            });
    }
})();

Views won’t load yet if you don’t add the <ui-view> directive in your index.html file. Since we want to load the view in the inner cover section of the index.html, so I place the <ui-view> directive right in the middle of the div with the class named inner cover. After modifying index.htm, your html should look like below,


<!DOCTYPE html>
<html lang="en" ng-app="answerit">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" media="screen" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css">
    <link rel="stylesheet" media="screen" href="css/cover.css">
    <title>Answer It!</title>
</head>
<body>
    <div class="site-wrapper">
        <div class="site-wrapper-inner">
            <div class="cover-container">
                <div class="masthead clearfix">
                    <div class="inner">
                        <h3 class="masthead-brand">Answer It!</h3>
                        <nav>
                            <ul class="nav masthead-nav">
                                <li class="active"><a href="#">Play</a></li>
                                <li><a href="#">How To</a></li>
                                <li><a href="#">About</a></li>
                            </ul>
                        </nav>
                    </div>
                </div>
                <div class="inner cover">
                    <ui-view></ui-view>
                </div>
                <div class="mastfoot">
                    <div class="inner">
                        <p>Answer It!, by <a href="https://twitter.com/@FiyazBinHasan">@FiyazBinHasan</a>.</p>
                    </div>
                </div>
            </div>
        </div>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.min.js"></script>
        <script src="js/app/app.module.js"></script>
</body>
</html>

Now run the app and navigate to different routes and see if it’s working. Of course it is working. Before I finish this part let’s do two things. We need to link the routes with our navigation links. It’s easy! Go to index.html file, in the navigation links section, replace href with another angular directive ui-sref and assign the appropriate state names. Here you go, before running the app lets modify the <li> tags a bit. We want to show which state is active right now, but if you run this app now, only play link will be decorated with active style (white underline) no matter which state you go. So in the <li> tags add an angular directive called ng-class and place a little logic there so that the white underline is shown under the active state link. Here is the little condition to check which state you are currently in.

For example, ng-class="{ 'active': $state.includes('play') }", here active class will be set to the play link if the state includes the play state.


<!DOCTYPE html>
<html lang="en" ng-app="answerit">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" media="screen" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css">
    <link rel="stylesheet" media="screen" href="css/cover.css">

    <title>Answer It!</title>
</head>

<body>
    <div class="site-wrapper">

        <div class="site-wrapper-inner">

            <div class="cover-container">

                <div class="masthead clearfix">
                    <div class="inner">
                        <h3 class="masthead-brand">Answer It!</h3>
                        <nav>
                            <ul class="nav masthead-nav">
                                <li ng-class="{ 'active': $state.includes('play') }"><a ui-sref="play">Play</a></li>
                                <li ng-class="{ 'active': $state.includes('howto') }"><a ui-sref="howto">How To</a></li>
                                <li ng-class="{ 'active': $state.includes('about') }"><a ui-sref="about">About</a></li>
                            </ul>
                        </nav>
                    </div>
                </div>

                <div class="inner cover">
                    <ui-view></ui-view>
                </div>

                <div class="mastfoot">
                    <div class="inner">
                        <p>Answer It!, by <a href="https://twitter.com/@FiyazBinHasan">@FiyazBinHasan</a>.</p>
                    </div>
                </div>

            </div>

        </div>

        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.min.js"></script>
        <script src="js/app/app.module.js"></script>
</body>

</html>

One last thing we need to do to make this thing work, go to app.module.js and chain a run() method after config(). Here in the run() method we are binding the current state to the $rootScope so that it handles the nested routing.


(function () {
    'use strict';

    angular.module('answerit', [
        'ui.router'
    ])
        .config(['$urlRouterProvider', '$stateProvider', configRoutes])
        .run(['$rootScope', '$state', configureStateWithScope]);

    function configRoutes($urlRouterProvider, $stateProvider) {
        $urlRouterProvider.otherwise('/play');

        $stateProvider
            .state('play', {
                url: '/play',
                templateUrl: 'templates/play.html'
            })
            .state('howto', {
                url: '/howto',
                templateUrl: 'templates/howto.html'
            })
            .state('about', {
                url: '/about',
                templateUrl: 'templates/about.html'
            });
    }

    function configureStateWithScope($rootScope, $state) {
        $rootScope.$state = $state;
    }
})();

N.B: If play has a nested state (i.e state(play.score) (#/play/score)) then it will also work. Thats becasue we bind our $state to $rootScope rather than to only $scope

Now in the app looks like all the routing is working. In part two we will start working on our game logic. See you later.