Skip to content Skip to sidebar Skip to footer

Angular And Breeze Edit Date Object

I have an AngularJS application where I want to edit a Date object that is being exposed by ASP Web API through BreezeJS. When I try to edit this field in a HTML form it doesn't qu

Solution 1:

Breeze maintains date properties as JavaScript Date objects when that's what you say they are in your metadata.

Breeze does not have its own Date type.

The HTML5 <input type="date" .../> date picker is not widely supported yet (see here) so I'm assuming you're relying on the Angular directive to help you.

That directive is designed to bind to a string, not a date object. This probably explains why the wheels are coming off.

I am sorely tempted to argue that the Ng directive should be smarter than this. It should do what it takes to bind to a Date object as well as a date string. I just might file that as a bug.

As you discovered, the HTML input tag "just works" if the type is "text". Obviously the date display and data entry are not what you want.

I think the ideal solution would be to have a directive that translates between date object and string value seamlessly. Probably could be done by decorating the existing Ng directive itself. Something to look into; we can always use your help; this is open source :-).

Meanwhile, you can create a defined property on your customSession type constructor.

See "Custom Constructors" in the documentation. Such a property would wrap the startDate property (startDateAsString?), parsing text in and formatting as string on the way out.

Here is a general purpose function to produce a Date wrapper property:

// Example: addDateWrapperProperty(SessionCtor, 'startDate', 'startDateAsString');functionaddDateWrapperProperty(ctor, propName, wrapperPropName) {

    Object.defineProperty(ctor.prototype, wrapperPropName, {
        get: function () { returnthis[propName].toString(); },
        set: function (value) { this[propName] = value; },
        enumerable: true,
        configurable: true
    });
}

Use it to define your startDateAsString wrapper property and then bind to this property when editing (bind to the real property for readonly display).

Because you don't want Breeze to serialize this, add it to the ctor AFTER registering that ctor with Breeze metadata as shown below.

I don't know for certain that this will give you the behavior you're looking for. I'd need to see your jsFiddle or plunkr to be sure. But I think it will do the trick. Let us know!

I'm certainly not saying this is the ultimate answer. I'm not sure what that answer is ... although I'm thinking about a directive as I said.

Hope this gets you out of the jam for now. Sorry it's such a PITA. Who knew Ng wouldn't understand Date objects?

Example

Here's an example extracted from an actual Breeze test:

/////  Test it //////varOrderCtor = function () { }; // do-nothing custom constructor// register the ctor FIRST, then add the property
manager.metadataStore.registerEntityTypeCtor('Order', OrderCtor);

addDateWrapperProperty(OrderCtor, 'orderDate', 'orderDateAsString');

// create new order with a test datevar testDate = newDate(2014,0,1,13,30); // 1/1/2014 1:30 pmvar order = em.createEntity('Order', {
    companyName: "test cust",
    orderDate: testDate
});

// confirm can read the date through the wrapper propertyexpect(order.orderDate.value).to.equal(testDate.value,
    "'order.orderDate' should return " + testDate);
expect(order.orderDateAsString).to.equal(testDate.toString(),
    "'order.orderDateAsString' should return " + testDate.toString());


var testDate2 = newDate();

// update orderDate by way of the wrapper property
order.orderDateAsString = testDate2.toString();

// confirm the update workedexpect(order.orderDate.value).to.equal(testDate2.value,
    "after update, 'order.orderDate' should return " + testDate2);
expect(order.orderDateAsString).to.equal(testDate2.toString(),
    "after update, 'order.orderDateAsString' should return " + testDate2.toString());

// confirm it is not a breeze-tracked propertyvar propInfo = order.entityType.getProperty('orderDateAsString');
expect(propInfo).to.equal(null, "'Order.orderDateAsString' is not known to metadata ");

Post a Comment for "Angular And Breeze Edit Date Object"