Search code examples
javascriptasp.net-mvcasp.net-mvc-4knockout.jsknockout-mvc

Knockout not showing data in mvc view


I created a simple project to learn mvc with knocout . here is how my things look like

View

<!DOCTYPE html>
 <html lang="en">
<head>
    <meta charset="utf-8" />
    <title>Home Page - My ASP.NET MVC Application</title>
    <link href="/favicon.ico" rel="shortcut icon" type="image/x-icon" />
    <meta name="viewport" content="width=device-width" />
    <link href="/Content/site.css" rel="stylesheet"/>

    <script src="/Scripts/modernizr-2.6.2.js"></script>

    <script src="/Scripts/jquery-1.8.2.js"></script>


    <script src="/Scripts/knockout-2.2.1.js"></script>
</head>
<body>
    <header>
        <div class="content-wrapper">
            <div class="float-left">
                <p class="site-title"><a href="/">your logo here</a></p>
            </div>
            <div class="float-right">
                <section id="login">
                        <ul>
    <li><a href="/Account/Register" id="registerLink">Register</a></li>
        <li><a href="/Account/Login" id="loginLink">Log in</a></li>
      </ul>

                </section>
                <nav>
                    <ul id="menu">
                        <li><a href="/">Home</a></li>
                        <li><a href="/Home/About">About</a></li>
                        <li><a href="/Home/Contact">Contact</a></li>
                    </ul>
                </nav>
            </div>
        </div>
    </header>
    <div id="body">

        <section class="content-wrapper main-content clear-fix">

   <table id="timesheets" class="table table-striped table-hover table-condensed">
   <thead>
    <tr>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Month</th>
        <th>Year</th>
    </tr>
 </thead>
 <tbody data-bind="foreach: viewModel.timesheets">
 <tr>
    <td data-bind="text: firstname"></td>
    <td data-bind="text: lastname"></td>
    <td data-bind="text: month"></td>
    <td data-bind="text: year"></td>
 </tr>
</tbody>
</table>
<script type="text/javascript">


$(function () {
ko.applyBindings(viewModel);
viewModel.loadTimesheets();
});
function timesheet(timesheet) {
this.id = ko.observable(timesheet.id);
this.firstname = ko.observable(timesheet.firstname);
this.lastname = ko.observable(timesheet.lastname);
this.month = ko.observable(timesheet.month);
this.year = ko.observable(timesheet.year);
}
var viewModel = {
timesheets: ko.observableArray([]),

loadTimesheets: function () {
    var self = this;
    $.getJSON(
        '/api/timesheet',
    function (timesheets) {
        self.timesheets.removeAll();
        $.each(timesheets, function (index, item) {
            self.timesheets.push(new timesheet(item));
        });
    }
     );
   }
};

   </script>
        </section>
    </div>
    <footer>
        <div class="content-wrapper">
            <div class="float-left">
                <p>&copy; 2013 - My ASP.NET MVC Application</p>
            </div>
        </div>
    </footer>


</body>
</html>

Controller

    public IEnumerable<TimeSheet> GetTimeSheets()
    {
        return db.TimeSheet.AsEnumerable();
    }

When page load this method is called and it return data as i can see in firebug

this is the result returned

[{"Id":1,"FirstName":"Ahsan","LastName":"Ashfaq","Month":8,"Year":2013},{"Id":2,"FirstName":"Ahsan","LastName":"Ashfaq","Month":9,"Year":2013},{"Id":3,"FirstName":"Ahsan","LastName":"Ashfaq","Month":10,"Year":2013}]

Update Image of table View in console Thanks in advance


Solution

  • The casing of the property names does matter. And because of the C# naming convention on the server side your JSON response have upper case Id and FirstName etc. property names.

    So you need to use the proper casing when creating your timesheet objects

    function timesheet(timesheet) {
        this.id = ko.observable(timesheet.Id);
        this.firstname = ko.observable(timesheet.Firstname);
        this.lastname = ko.observable(timesheet.Lastname);
        this.month = ko.observable(timesheet.Month);
        this.year = ko.observable(timesheet.Year);
    }