Fabric.js subclassing fabric.Group - Error: "Cannot read property 'async' of undefined" when load from JSON Fabric.js subclassing fabric.Group - Error: "Cannot read property 'async' of undefined" when load from JSON json json

Fabric.js subclassing fabric.Group - Error: "Cannot read property 'async' of undefined" when load from JSON


The error "Cannot read property 'async' of undefined" is raised because no "klass" can be found - https://github.com/kangax/fabric.js/blob/master/src/util/misc.js#L214-215.

You have to assign your custom object to fabric object - otherwise canvas.loadFromJSON() doesn't work.

var fabric.CustomGroup = fabric.util.createClass(fabric.Group, {    type : 'customGroup',    initialize : function(objects, options) {        options || ( options = { });        this.callSuper('initialize', objects, options);        this.set('customAttribute', options.customAttribute || 'undefinedCustomAttribute');    },    toObject : function() {        return fabric.util.object.extend(this.callSuper('toObject'), {            customAttribute : this.get('customAttribute')        });    },    _render : function(ctx) {        this.callSuper('_render', ctx);    }});

Additionally you have to declare the fromObject method - it's needed for loadFromJSON.In this case your object is load synchronous.

fabric.CustomGroup.fromObject = function (object, callback) {    var _enlivenedObjects;    fabric.util.enlivenObjects(object.objects, function (enlivenedObjects) {        delete object.objects;        _enlivenedObjects = enlivenedObjects;    });    return new fabric.CustomGroup(_enlivenedObjects, object);};

If your custom object is loaded async you have to do this:

fabric.CustomGroup.fromObject = function (object, callback) {    fabric.util.enlivenObjects(object.objects, function (enlivenedObjects) {        delete object.objects;        callback && callback(new fabric.CustomGroup(enlivenedObjects, object));    });};fabric.CustomGroup.async = true;

I've made a small jsfiddle testcase: http://jsfiddle.net/Kienz/qPLY6/