0

I'm new to Angular but I've done a couple basic examples successfully. Now I'm looking at starting my first real world Angular/MVC/WebAPI app. It's going to be a Time Card type app and the first thing I'm looking to do is display the current time of the local user. I did to a basic HelloWorld with Angular on the Index.cshtml page just to make sure my references to Angular were correct. That worked....BTW, I'm using Angular v1.5.

I found the following post and I'm trying to use a mixture of the code.

http://www.codeproject.com/Articles/806029/Getting-started-with-AngularJS-and-ASP-NET-MVC-Par

http://stackoverflow.com/questions/23383233/how-to-make-a-ticking-clock-time-in-angularjs-and-html

However I'm not getting it to work and it's probably something simple I'm missing, yet I don't see it.

Here is my _Layout.csthml. I have the ng-app and ng-controller listed in the <html> tag

<!DOCTYPE html>
<html ng-app="VirtualTimeClockApp" ng-controller="LandingPageController">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title</title>
    @Styles.Render("~/Content/css")

</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li>@Html.ActionLink("Home", "Index", "Home")</li>
                    <li>@Html.ActionLink("About", "About", "Home")</li>
                    <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                </ul>
                @Html.Partial("_LoginPartial")
            </div>
        </div>
    </div>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
        </footer>
    </div>

    @Scripts.Render("~/bundles/bootstrap")
    @Scripts.Render("~/bundles/angular")
    @Scripts.Render("~/bundles/VirtualTimeClockApp")
    @RenderSection("scripts", required: false)

</body>
</html>

Here is my Home/Index.cshtml

@model VirtualTimeClock.ViewModels.HomeViewModel

@{
    ViewBag.Title = "Home Page";
}

<div class="jumbotron">
    <h1>@Model.currentServerTime</h1>

    <div ng-controller='TimeCtrl'>
        <p>{{ clock | date:'HH:mm:ss'}}</p>
    </div>

    <p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p>
    <p><a href="http://asp.net" class="btn btn-primary btn-lg">Learn more &raquo;</a></p>
</div>

Here is my BundleConfig.cs file. Next to the last Bundles.Add is where I bundle the controller directory and the main .js file.

namespace VirtualTimeClock
{
    public class BundleConfig
    {
        // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862
        public static void RegisterBundles(BundleCollection bundles)
        {
            bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
                      "~/Scripts/bootstrap.js"));

            bundles.Add(new ScriptBundle("~/bundles/angular").Include(
                      "~/Scripts/angular.js"));

            bundles.Add(new ScriptBundle("~/bundles/VirtualTimeClockApp")
                    .IncludeDirectory("~/Scripts/Controllers", "*.js")
                    .Include("~/Scripts/VirtualTimeClock.js"));

            bundles.Add(new StyleBundle("~/Content/css").Include(
                      "~/Content/bootstrap.css",
                      "~/Content/site.css"));
        }
    }
}

This is my VirtualTimeClock.js file. The thing I'm not 100% on here is the declaration of VirtrualTimeClockApp is then adding a module to the "VirtualTimeClockApp" that is referenced in the ?

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

VirtualTimeClockApp.controller('LandingPageController', LandingPageController);

This is my LandingPageController.js file.

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

module.controller('TimeCtrl', function ($scope, $interval) {
    var tick = function () {
        $scope.clock = Date.now();
    }
    tick();
    $interval(tick, 1000);
});
7
  • Are you getting any erros in the console and when you look at the page source, check the order that the scripts are being called - it might be calling LandingPageController.js before VirtualTimeClock.js Commented Mar 9, 2016 at 20:17
  • @christiandev....No errors that I can see. It just displays {{ clock | date:'HH:mm:ss'}} in the page. So something is not tied together correctly. Commented Mar 9, 2016 at 20:21
  • You define a LandingPageController but i do not see the function you are referring to. There should be a function LandingPageController(){}; in your code somewhere. Commented Mar 9, 2016 at 20:24
  • @KreepN....again, I'm still learning but in the VirtualTimeClock.js file it creates a controller called 'LandingPageController' and I'm assuming the next property is the LandingPageController.js even though it just says LandingPageController. Then in LandingPageController.js file has a function aliased by 'TimeCtrl' will calls the function to set the $scope.clock to the current date. At least that's the way I'm understanding it. Commented Mar 9, 2016 at 20:36
  • @Caverman I'm assuming the next property is the LandingPageController.js is a wrong assumption. The second parameter is the function name, which you have not defined. Angular does not load JS files from controllers like that. Commented Mar 9, 2016 at 20:39

2 Answers 2

1

Change your VirtualTimeClock.js to...

(function () {
    'use strict';
    angular.module('VirtualTimeClockApp', []);
})();

(function () {
    'use strict';

    angular
        .module('VirtualTimeClockApp')
        .controller('LandingPageController', LandingPageController);


    function LandingPageController() {

    }
})();

and the other file to:

(function () {
    'use strict';

    angular
        .module('VirtualTimeClockApp')
        .controller('TimeCtrl', TimeCtrl);

    TimeCtrl.$inject = ['$scope', '$interval'];

    function TimeCtrl($scope, $interval) {
        var tick = function () {
            $scope.clock = Date.now();
        }
        tick();
        $interval(tick, 1000);
    }
})();

and reorder the bundle...

 bundles.Add(new ScriptBundle("~/bundles/VirtualTimeClockApp")
                    .Include("~/Scripts/VirtualTimeClock.js")
                    .IncludeDirectory("~/Scripts/Controllers", "*.js")
                    );

enter image description here

I think the main issue was the bundle order, but it's cleaner to use IIFE. Also, worth reading this style guide.

Sign up to request clarification or add additional context in comments.

2 Comments

BINGO! with a small change. I used your code initially but it wasn't working (even though I think it should have been). Then I decided that I wanted the controller to work in a specific section of the page and not the every page that I'm going to build. So I moved ng-controller="LandingPageController" from the HTML tag in the _Layout.cshtml page to the <div class="jumbotron"> which is where I want this piece of angular to work. Then it started working. Thanks for the help! I'm sure there will be other questions coming soon.
@Caverman, moving the placement lower in the dom shouldn't make any difference - I think it was the bundling. Either way, check out that style guide, it really helped me when starting out. Good luck.
0

Remove the brackets from here

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

And create a function called LandingPageController. It should look like this:

var VirtualTimeClockApp = angular.module('VirtualTimeClockApp');

VirtualTimeClockApp.controller('LandingPageController',   LandingPageController);

function LandingPageController() {}

If you use the brackets you are creating a new module, which in this case is already created on your LandingPageController.js file


2 Comments

@Sergio....thanks for the suggestion. I removed the brackets but it's still not working. I'll leave the brackets off. There were in the sample code I pulled from one of the links above. I now have "var module = angular.module('VirtualTimeClockApp');" in my LandingPageController.js file.
@Caverman I updated the answer. I got confused with the names earlier. The was two issues, the LandingPageController function was not defined, and also the brackets ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.