Object loses set function after being restored back from json

I have circles and lines on canvas (i did rebuld demo from fabric.js to fit my needs ) and while moving circles over the canvas also lines are following specif pressed moved circle. Everything works fine with attached move handler below.

But after storing canvas to Json variable jsonToPHP= JSON.stringify(canvas.toObject(['id','name','line1','line2'])); and retrieving them back from variable

 canvas.loadFromJSON( jsonToPHP, function() {    
    canvas.renderAll();
      });

to redraw canvas i get next error when i am trying to move objects on canvas again.
(check attached picture (green ellipse displays correct behavior before using of Json and red one is after using of Json).

Uncaught TypeError: obj.line1.set is not a function
at i.moveHandler (createObject1.js?ver=1.0.0:538)

How to resolve this problem?

 var leftx2,topy2;
var moveHandler = function (evt) {
    var obj = evt.target;
  leftx2 = obj.get('left');
  topy2 = obj.get('top');
   
    obj.line1 && obj.line1.set({ 'x2': obj.left, 'y2': obj.top });
    obj.line2 && obj.line2.set({ 'x1': obj.left, 'y1': obj.top });
}

Hi @ivangolubar and welcome to the forums.

When you use JSON.stringify the object is converted to a string and therefore will lose any functions inside of it. A potential solution is that you just store a function name string that points to an actual function in your code and that you handle that scenario appropriately.

e.g.

var myObject = {
    myFunction : 'functionName'
};

var serializedObject = JSON.stringify(myObject);
var myDecodedObject = JSON.parse(serializedObject);

if (typeof window[myDecodedObject.myFunction] === 'function') {
    window[myDecodedObject.myFunction]();
}

Hope the tip helps,

Andres

Thank you for the answer.
It is in general clear to me what is the solution. but i am not able to implement it on my case.
I did next code from my code. I can not test it on any online code tester. I don’t know the reason why.
But I think that is enough clear to You what is the purpose of this code.
In short words on each click on canvas circle is drawn with line, to get polyline on the end, with clicking on last circle.
Move handler then takes care to move also lines attached to specific circle when circle is dragged around on canvas.
Code works fine before storing and retrieving it back from Json. But once Json is used lines are not folloving circles any more.
This code is modification of code on the link which i added in beginning of this question.

Let me now get back to your solution.
I did start from next but no result.


var moveHandler = function (evt) {
    var obj = evt.target;
 if (typeof window[obj.line1.set] === 'set') {
     console.log(obj.line1.type);
  } 
}

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

 <script src="http://fabricjs.com/lib/fabric.js"></script>
 
<style></style>

<script>
var canvas = new fabric.Canvas('c5');
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';

var line1=[];

 function makeLine(coords) {
    return new fabric.Line(coords, {
      fill: 'red',
      stroke: 'red',
      strokeWidth: 5,
    selectable: false,
     name:'polyline'
    });
 }
 var circle1=[];
  function makeCircle(left, top, line1, line2) {
    var c = new fabric.Circle({
      left: left,
      top: top,
      strokeWidth: 2,
      radius: 6,
      fill: '#fff',
      stroke: '#666',
      name:'polyline'
    });
    c.hasControls = c.hasBorders = false;

    c.line1 = line1;
    c.line2 = line2;

    return c;
  }
 
 
var clickonobject ;
var objectIndex;
var lineCount=0;
var posX1=0;
var posY1=0;
var posX2=0;
var posY2=0;
function drawPoly(){
   
       if (lineCount!=0){
       line1[lineCount] = makeLine([posX1, posY1, posX2, posY2 ]);
       canvas.add(line1[lineCount]);
        console.log(line1[lineCount].type,line1[lineCount].name);
       } 

     if (lineCount==0){
          circle1[lineCount]=makeCircle( posX2, posY2, null,null);
          canvas.add(circle1[lineCount]); 
      }
      if (lineCount>0){
         circle1[lineCount]= makeCircle(line1[lineCount].get('x2'), line1[lineCount].get('y2'), line1[lineCount],null);
         canvas.add(circle1[lineCount]); 
         circle1[lineCount-1].line2 =line1[lineCount];
      } 
      
     lineCount=lineCount+1;    
}

canvas.on('mouse:down', function(e) {
    var obj2 = e.target;
    if (obj2!= null){console.log(obj2.type);}
   
  if (obj2==null){
         posX1 = posX2;
         posY1 = posY2;
         var pointer = canvas.getPointer(e.e);
         posX2 = pointer.x;
         posY2 = pointer.y;
         drawPoly();
      }else{lineCount=0;}
});

 var leftx2,topy2;
var moveHandler = function (evt) {
    var obj = evt.target;
  leftx2 = obj.get('left');
  topy2 = obj.get('top');
   //console.log(leftx2);
  //console.log(topy2);
    obj.line1 && obj.line1.set({ 'x2': obj.left, 'y2': obj.top });
    obj.line2 && obj.line2.set({ 'x1': obj.left, 'y1': obj.top });
}


var jsonToPHP;
function  saveJsonF(){
jsonToPHP= JSON.stringify(canvas.toObject(['id','name','line1','line2']));
canvas.clear();
}

document.getElementById("saveJsonID").onclick = saveJsonF;
function  getJsonF(){
    canvas.loadFromJSON(jsonToPHP, function() {    
    canvas.renderAll();
      });
}

document.getElementById("getJsonID").onclick = getJsonF; 
;

</script>
</head>
<body>
       <input type="button"  id="saveJsonID" value=" saveJson"/> 
       <input type="button"   id="getJsonID" value=" getJson"/>
      
       <canvas  id="c5" width="1060" height="550"   style="border: 5px solid red" > 
      

</div>
</body></html>

getJsonF; {"objects":[{"type":"circle","originX":"center","originY":"center","left":115,"top":77.91,"width":12,"height":12,"fill":"#fff","stroke":"#666","strokeWidth":1,"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,"radius":6,"startAngle":0,"endAngle":6.283185307179586,"name":"1","line1":null,"line2":{"type":"line","originX":"center","originY":"center","left":191.5,"top":148.91,"width":153,"height":142,"fill":"green","stroke":"green","strokeWidth":4,"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,"x1":-76.5,"x2":76.5,"y1":-71,"y2":71}},{"type":"text","originX":"center","originY":"center","left":115,"top":62.91,"width":8,"height":18.08,"fill":"orange","stroke":null,"strokeWidth":1,"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,"text":"1","fontSize":16,"fontWeight":"bold","fontFamily":"Times New Roman","fontStyle":"","lineHeight":1.16,"textDecoration":"","textAlign":"left","textBackgroundColor":"","charSpacing":0,"id":"1Text","name":"1"},{"type":"line","originX":"center","originY":"center","left":191.5,"top":148.91,"width":153,"height":142,"fill":"green","stroke":"green","strokeWidth":4,"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,"name":"1","x1":-76.5,"x2":76.5,"y1":-71,"y2":71},{"type":"circle","originX":"center","originY":"center","left":268,"top":219.91,"width":12,"height":12,"fill":"#fff","stroke":"#666","strokeWidth":1,"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,"radius":6,"startAngle":0,"endAngle":6.283185307179586,"name":"1","line1":{"type":"line","originX":"center","originY":"center","left":191.5,"top":148.91,"width":153,"height":142,"fill":"green","stroke":"green","strokeWidth":4,"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,"x1":-76.5,"x2":76.5,"y1":-71,"y2":71},"line2":{"type":"line","originX":"center","originY":"center","left":211.5,"top":270.91,"width":113,"height":102,"fill":"green","stroke":"green","strokeWidth":4,"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,"x1":56.5,"x2":-56.5,"y1":-51,"y2":51}},{"type":"line","originX":"center","originY":"center","left":211.5,"top":270.91,"width":113,"height":102,"fill":"green","stroke":"green","strokeWidth":4,"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,"name":"1","x1":56.5,"x2":-56.5,"y1":-51,"y2":51},{"type":"circle","originX":"center","originY":"center","left":155,"top":321.91,"width":12,"height":12,"fill":"#fff","stroke":"#666","strokeWidth":1,"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,"radius":6,"startAngle":0,"endAngle":6.283185307179586,"name":"1","line1":{"type":"line","originX":"center","originY":"center","left":211.5,"top":270.91,"width":113,"height":102,"fill":"green","stroke":"green","strokeWidth":4,"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,"x1":56.5,"x2":-56.5,"y1":-51,"y2":51},"line2":null},{"type":"circle","originX":"center","originY":"center","left":34,"top":66.91,"width":12,"height":12,"fill":"#fff","stroke":"#666","strokeWidth":1,"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,"radius":6,"startAngle":0,"endAngle":6.283185307179586,"name":"2","line1":null,"line2":{"type":"line","originX":"center","originY":"center","left":36.5,"top":167.91,"width":5,"height":202,"fill":"green","stroke":"green","strokeWidth":4,"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,"x1":-2.5,"x2":2.5,"y1":-101,"y2":101}},{"type":"text","originX":"center","originY":"center","left":34,"top":51.91,"width":8,"height":18.08,"fill":"orange","stroke":null,"strokeWidth":1,"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,"text":"2","fontSize":16,"fontWeight":"bold","fontFamily":"Times New Roman","fontStyle":"","lineHeight":1.16,"textDecoration":"","textAlign":"left","textBackgroundColor":"","charSpacing":0,"id":"2Text","name":"2"},{"type":"line","originX":"center","originY":"center","left":36.5,"top":167.91,"width":5,"height":202,"fill":"green","stroke":"green","strokeWidth":4,"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,"name":"2","x1":-2.5,"x2":2.5,"y1":-101,"y2":101},{"type":"circle","originX":"center","originY":"center","left":39,"top":268.91,"width":12,"height":12,"fill":"#fff","stroke":"#666","strokeWidth":1,"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,"radius":6,"startAngle":0,"endAngle":6.283185307179586,"name":"2","line1":{"type":"line","originX":"center","originY":"center","left":36.5,"top":167.91,"width":5,"height":202,"fill":"green","stroke":"green","strokeWidth":4,"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,"x1":-2.5,"x2":2.5,"y1":-101,"y2":101},"line2":null}]}

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.