Saturday, 2 January 2016

Cloning Reddit to learn ASP.NET 5 - Part 4

In the previous post we ended up again with a broken, although partially this time, application let's try to fix it.

The problem was that it could not resolve the service type for IRedditRepository as we were not telling how to inject the dependency properly, which is done on the ConfigureServices method on Startup.cs:

public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddMvc();
            services.AddEntityFramework()
                .AddSqlServer()
                .AddDbContext<RedditContext>();

            services.AddScoped<IRedditRepository, RedditRepository>();
        }
AddScoped will use the same instance for each request, could have used AddSingleton or AddInstance.

We try running this again and we see this:


So it's working but there is nothing there, we'll have a look at this later on.

Now let's try to look at the homepage, which at the moment looks like this.

This doesn't look like Reddit, so let's do a bit of editing.

Delete the Contact.cshtml and About.cshtml files, in the Home folder

Edit Index.cshtml so that it looks like this:

@{
    ViewData["Title"] = "Reddit";
}
This is the _Layout.cshtml file, which can be thought of as a master page or template page. I've removed pretty much everything from it that might be rendered.
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Reddit</title>

    <environment names="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
        <link rel="stylesheet" href="~/css/site.css" />
    </environment>
    <environment names="Staging,Production">
        <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.5/css/bootstrap.min.css"
              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    </environment>
</head>
<body>
    <div>
        @RenderBody()       
    </div>

    <environment names="Development">
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
    </environment>
    <environment names="Staging,Production">
        <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js"
                asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                asp-fallback-test="window.jQuery">
        </script>
        <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.5/bootstrap.min.js"
                asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
                asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal">
        </script>
        <script src="~/js/site.min.js" asp-append-version="true"></script>
    </environment>

    @RenderSection("scripts", required: false)
</body>
</html>
The end result of all this should be an empty page.

I've left RenderBody and RenderSection method calls intact as they will come in handy later. In essence, they are used to merge in the content from the actual pages and to load the scripts needed respectively.

Since this is a modern app I'm going to use AngularJS, which is probably past it's prime now but there you go.

The simplest thing to do this is by using the manage bower packages:


This will display this page:


This is the result on the bower.json file, which should be noted is not shown by visual studio but it's there on the src\Reddit folder:

{
  "name": "ASP.NET",
  "private": true,
  "dependencies": {
    "bootstrap": "3.3.5",
    "jquery": "2.1.4",
    "jquery-validation": "1.14.0",
    "jquery-validation-unobtrusive": "3.2.4",
    "angular": "1.4.6"
  }
}
So let's add Angular to Reddit

I've added a new file called redditApp.js to wwwroot/js, which contains the following:
(function () {

  "use strict";

  var redditApp = angular.module('redditApp', []);

redditApp.controller('SubRedditListCtrl', function($scope) {
  $scope.subReddits = [
    {'name': 'Gadgets'},    
    {'name': 'Sports'},
    {'name': 'Gaming'},
    {'name': 'Pics'},
  ];
});
  
})();

I've hard coded a few subreddits to have something to display but we will soon get them from the database. In essence, the above is a self executing function containing an extremely simple angular controller that has an array of objects.

I have modified the Index.cshtml like this:

@{
    ViewData["Title"] = "Reddit";
}
@section scripts {

    <script src="~/lib/angular/angular.js"></script>
    <script src="~/js/redditapp.js"></script>
}
<div ng-app="redditApp">
    <div ng-controller="SubRedditListCtrl">
        <ul class="list-inline">
            <li ng-repeat="subReddit in subReddits">
                <span>{{subReddit.name}}</span>
            </li>
        </ul>
    </div>
</div>

Note the angular directives? ng-app, ng-controller and ng-repeat and also note the angular bingind {{subReddit.name}}

This is what Reddit looks like now:

No comments:

Post a Comment