Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON Serialization ignores custom attributes in fabric.js after loadFromJSON

I am running into a strange issue with serialization in fabric.js.

I have created a custom Group object with a couple of custom properties. I have implemented the toObject() method to handle the custom properties.

 var customGrpFieldOptions = {
      "name":"fabric-custom-grp",

      "includeCField1" : true,
      "includeCField2" : false,
      "includeCField3" : false,
      "includeCField4" : true
  };

  var customGrpObject  = new fabric.Group([], customGrpFieldOptions);
  customGrpObject.toObject = (function(toObject) {
    return function() {
      return fabric.util.object.extend(toObject.call(this), {
          includeCField1: this.includeCField1,
          includeCField2: this.includeCField2,
          includeCField3: this.includeCField3,
          includeCField4: this.includeCField4
      });
    };
  })(customGrpObject.toObject);

I serialize the canvas object to save it. The serialized JSON has the custom attributes.

When I reload the object to canvas, I can see that the object has the custom attributes. However, when I serialize the canvas again, the properties do not get included.

I have created a JSFiddle to demonstrate the issue. https://jsfiddle.net/bbcstar/9x48kk7f/

What is going wrong here? Am I missing something?

Any help would be much appreciated!

like image 331
BBC Avatar asked Oct 03 '16 12:10

BBC


1 Answers

Andrea Bogazzi(@asturur) suggested I should be passing an array of custom fields that need to be included for serialization. That helps resolve this specific issue.

However what is still surprising to me is why serialization works fine in the original state without requiring to pass the array.

var json = JSON.stringify( canvas.toJSON() );

Serialized Canvas before loadFromJSON

json : {"objects":[{"type":"group","originX":"left","originY":"top","left":0,"top":0,"width":0,"height":0,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"objects":[],"includeCField1":true,"includeCField2":false,"includeCField3":false,"includeCField4":true}],"background":""} 

After loading the serialized state to canvas using loadFromJSON, when we serialize the object again, we need to explicitly mention the custom fields that need to be included.

var json2 = JSON.stringify( canvas.toJSON(["includeCField1", "includeCField2","includeCField3","includeCField4"]) );

Serialized Canvas after loadFromJSON:

{"objects":[{"type":"group","originX":"left","originY":"top","left":0,"top":0,"width":0,"height":0,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,**"includeCField1":true,"includeCField2":false,"includeCField3":false,"includeCField4":true**,"objects":[]}],"background":""}
like image 67
BBC Avatar answered Oct 29 '22 03:10

BBC