Search code examples
knockout.jsbreezehottowelmomentjs

Formatting Dates retrieved by Breeze using moment.js. Hot Towel Template


I have been following John Papa's Hot Towel Tutorials and I have a c# class that looks like this:

public class Lead
{
    public int LeadId { get; set; }
    public DateTime? LastContactMade { get; set; }
    public DateTime? LastContactAttempt { get; set; }
}

I am retrieving the data in the client using breeze but I cannot figure out how to format the date using moment.js and knockout.js. When I display the date un-formatted using the following knockout binding:

<section data-bind="foreach: leads">
    <span data-bind="text: lastContactMade"></span>
    <span data-bind="text: lastContactAttempt"></span>
</section>

The dates are displayed in the following format:

Wed Feb 27 2013 03:28:00 GMT-0800 (Pacific Standard Time)

When I try to format them using moment.js as follows:

<section class="article-list" data-bind="foreach: leads">
    <span data-bind="text: moment(lastContactMade).format('l LT')"></span>
    <span data-bind="text: moment(lastContactAttempt).format('l LT')"></span>
</section>

the resulting output looks like this:

NaN/NaN/0NaN 12:NaN AM

I've also tried doing the formatting in my LeadInitializer located in my model (which is what I'd prefer) by doing this:

function leadInitializer(lead) {
    lastContactAttempt = lead.lastContactAttempt;
    lastContactMade = lead.lastContactMade;
    lead.lastContactAttempt = ko.computed({
        read: function () {
            return moment(lastContactAttempt).format('l LT');
        },
        write: function () {
            return lastContactAttempt;
        }
    });
    lead.lastContactMade = ko.computed({
        read: function () {
            return moment(lastContactMade).format('l LT');
        },
        write: function () {
            return lastContactMade;
        }
    });
};

Doing this, I still get the same output:

NaN/NaN/0NaN 12:NaN AM

i've read the post at

Date formatting issues with Knockout and syncing to breeze.js entityAspect modified

but it did not seem to help me here. Can someone please show me where I'm going wrong?


Solution

  • I think you just forgot to unwrap the Knockout observables:

    // add parentheses here......................vv
    <span data-bind="text: moment(lastContactMade()).format('l LT')"></span>
    <span data-bind="text: moment(lastContactAttempt()).format('l LT')"></span>
    

    When you load an entity with Breeze, all the properties will be created as Knockout observables. You can use these observables directly in your data-bind Knockout bindings, but since moment.js won't know what to do with a Knockout observable, you have to first unwrap the observable to get the plain JavaScript Date value.