ciscoheat/dataclass

Fields with default values in nested DC classes

Closed this issue · 2 comments

Class fields defined with default values seem to be handled differently when instantiated via a wrapper DataClass compared to when instantiated directly.

In the following example, the User.age field has a default value of 20. When instantiated directly, the resulting User object has the field 'age' with value 20 - as expected.
But when instatiating a User object via a wrapper class, the resulting User object doesn't have an 'age' field at all.

Bug or feature..? :-)

static function main() {
        var user = new User(Json.parse('{ "name": "Jonas" }'));
        trace(user); 
        // { age: 20, name: 'Jonas' } - correctly including the 'age' parameter
       
        var wrapper = new Wrapper(Json.parse('{
            "user": { "name": "Jonas" },
            "otherstuff": [ "UserEmail1" ]
        }'));
        trace(wrapper.user); 
        // { name: 'Jonas' } - 'age' parameter missing!
}

class User implements DataClass {
    public var age: Int = 20; // Default value 20
    public var name:String;
}

class Wrapper implements DataClass {
    public var user:User;
    public var otherstuff:Array<String>;
}

The Haxe "feature" is that if you pass anything Dynamic into the constructor, JSON for example, the type is just assumed to be correct and assigned to the field, and it usually looks like it works on dynamic targets until some surprise like this comes up. The solution is to use the JSON converter instead:

using dataclass.JsonConverter; 
...

var wrapper = Wrapper.fromJson(Json.parse('{
...

There was a small bug in the converter however, so you need to update haxelib again.

Ah, I tried the JsonConverter.fromJson(), but with no success because of that now-gone bug.
Thanx! 👍