1

Running into a strange bug.

I have a form that binds to an object in angular. This object inherits from a base form that contains fields used across all forms, such as FirstName, LastName, etc...

Here is an example of how this is set-up:

myApp.factory('BaseForm', function ()
{
    var BaseForm = function ()
    {
        Object.defineProperty(this, "Foo",
        {
            get: function () { return BaseForm.Foo; },
            set: function (newValue) { BaseForm.Foo = newValue; }
        });
    }

    //Foo is defined as both a static and instance property so value
    //can be shared across all instances, but also bound directly in view

    BaseForm.Foo= '';
    BaseForm.prototype = {
        Foo= ''
    };

    return BaseForm;
});

myApp.factory("ChildForm", ["BaseForm", function (BaseForm)
{
    var _base = BaseForm;

    var ChildForm = function ()
    {
        //call the base-level constructor to initialize core properties
        _base.apply(this, arguments);

        //... other child specific code here...
    };

    var _childProperties = {
        Bar: { enumerable: true, configurable: false, writable: true, value: '' }
    };

    ChildForm.prototype = Object.create(_base.prototype, _childProperties);
    ChildForm.prototype.constructor = ChildForm;

    return ChildForm;
}]);

When I submit the form in Chrome, all properties, including those inherited from the base class, are serialized correctly and sent across the wire. The resulting JSON string looks like this:

"{ "Foo": "abc", "Bar": 123 }"

But when I submit the same from in IE (versions 9-11), none of the inherited fields are serialized or sent, and the resulting JSON string looks like this:

"{ "Bar": 123 }"

I have verified that the values are populating correctly in the model, they're just not being serialized in IE. Can anyone help me understand why this is happening and what I need to do to fix it?

Update

So, have not figured out why this is happening, but after reading this post, I added a toJSON() override method in my base class and was able to force this to serialize correctly in all browsers. Not ideal, but was the quickest solution with the least impact to existing code. However, the original question still stands if someone can answer the why part.

Here is a PLUNK demonstrating the behavior:

Thanks!

Community
  • 1
  • 1
Joshua Barker
  • 987
  • 2
  • 11
  • 23
  • `Foo= ''` in prototype? – hawk Jun 11 '14 at 04:48
  • Why you declaring `Foo` twice, in function body and through prototype ? – hawk Jun 11 '14 at 04:53
  • Sorry, typo... s/b Foo: ''. And as I stated in my code above, Foo is declared as a static property on the base class / function, and then declared as an instance property on the prototype. This is a trick I use when I need to reference a static property, but want to do so within the context of an instance, so that I don't have to hard-code a reference to the static class. This comes in handy when binding my model to a view (ex: ng-model="Foo" vs ng-model="BaseClass.Foo"). But this has no impact on my initial question. The same issue occurs regardless of how the property is declared. – Joshua Barker Jun 11 '14 at 15:29
  • Your instance will never rich prototype, because of name collision. It will always stop on `BaseForm.Foo` – hawk Jun 11 '14 at 16:30
  • I'm sorry, but that has nothing to do with this. This problem occurs regardless of whether I have a static property or not. After some additional digging, it looks like this happens when a property is declared in the prototype, but not re-declared in the constructor. This properties will display correctly if referenced individually (i.e. _childForm.Foo), but they do not appear is serialized to JSON via angular.toJson(...). This is the real problem. Does anyone know why? – Joshua Barker Jun 12 '14 at 07:32
  • Check this out http://jsbin.com/fimagawa/1/edit?js,console . prototype.Foo always ignored – hawk Jun 12 '14 at 09:46

0 Answers0