jerosoler / Drawflow

Simple flow library 🖥️🖱️
https://jerosoler.github.io/Drawflow/
MIT License
4.42k stars 714 forks source link

TypeError: Cannot read properties of undefined (reading 'Home') while importing #782

Closed JCPreethi closed 7 months ago

JCPreethi commented 8 months ago

Hello @jerosoler

I'm trying to import the json that i have exported to sql server database, but i keep getting the - TypeError: Cannot read properties of undefined (reading 'Home') while importing error.

This is the data i'm sending on button click to the database

const dataExport = this.editor.export();
dataExport = JSON.stringify(dataExport);

and this is how i am trying to import it in vue 2 using watch

const container = this.$refs.drawflowContainer; this.editor = new Drawflow(container); this.editor.start(); try { this.editor.import(JSON.parse(JSON.stringify(this.activedetails['flow']['header']['htmlData']))); } catch (err) { console.log('Invalid Data',err) }

P.S - tried to import just with JSON.parse() but it threw the below error

Invalid Data SyntaxError: Bad control character in string literal in JSON at position 813 (line 1 column 81).

What am i doing wrong here?

jerosoler commented 8 months ago

Compare "dataExport" with you "this.activedetails['flow']['header']['htmlData']"

Or console.log(this.activedetails['flow']['header']['htmlData'])

The "Home" module is required. You cannot modify the name of the first module.

Solution is your first module is not "Home":

JCPreethi commented 8 months ago

It does have a Home module

{ "drawflow": { "Home": { "data": { "1": { "id": 1, "name": "OriginalRepo", "data": {}, "class": "personalized", "html": "<div class=\"Blocks\"> <div class=\"block_div_one\">

OriginalRepo

<div class=\"block_div_two\"> <img src=\"/icons/OriginalRepo.svg\" alt width=\"25\" height=\"30\" />
<div class=\"block_div_three\"> <div class=\"api_name_block\"> <p class=\"api_name\">Activate account 1

<div class=\"badge badge-outlined text-wrap\" style=\"width:3rem;\"> POST <div class=\"block_div_four\"> <div class=\"block_ops\">
<img data-context=\"OriginalRepo\" class=\"drawflow-delete-button\" src=\"/icons/edit.svg\" v-b-toggle.APIOffcanvas width=\"14px\" height=\"14px\" />
<img src=\"/icons/close.svg\" width=\"14px\" height=\"14px\" />
<div class=\"blockId\"> 1 ", "typenode": false, "inputs": {}, "outputs": { "output_1": { "connections": [] } }, "pos_x": 259, "pos_y": 174 } } } } }

jerosoler commented 8 months ago

Review the html content node.

The example with you export:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.css" />
  <script src="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.js"></script>
  <style>
    #drawflow {
      position: relative;
      width: 100%;
      height: 800px;
      border: 1px solid red;
    }
  </style>
</head>
<body>
  <div>
    <div id="drawflow"></div>
  </div>
  <script>
    var id = document.getElementById("drawflow");
    const editor = new Drawflow(id);
    const toImport = {
      "drawflow": {
        "Home": {
          "data": {
            "1": {
              "id": 1,
              "name": "OriginalRepo",
              "data": {},
              "class": "personalized",
              "html": "<div>Content</div>",
              "typenode": false,
              "inputs": {},
              "outputs": {
                "output_1": {
                  "connections": []
                }
              },
              "pos_x": 259,
              "pos_y": 174
            }
          }
        }
      }
    }
    editor.start();
    editor.import(toImport)
  </script>
</body>
</html>
JCPreethi commented 8 months ago

I am using vue2 and the html template template has no issues. when i try to import it manually like below:

const container = this.$refs.drawflowContainer;
          this.editor = new Drawflow(container);
          const toImport = {
            "drawflow": {
              "Home": {
                "data": {
                  "1": {
                    "id": 1,
                    "name": "OriginalRepo",
                    "data": {},
                    "class": "personalized",
                    "html": "<div>Content</div>",
                    "typenode": false,
                    "inputs": {},
                    "outputs": {
                      "output_1": {
                        "connections": []
                      }
                    },
                    "pos_x": 259,
                    "pos_y": 174
                  }
                }
              }
            }
          }
          this.editor.start();

          this.editor.import(toImport); 

this works, the issue arises only when im trying to import the data received from a get request.

For reference, i'm creating a new drawflow on mount and im trying to import it on a button click which triggers the watch variable

mounted(){
        const container = this.$refs.drawflowContainer;
        if (container) {
          this.editor = new Drawflow(container);
          var elements = document.getElementsByClassName('drag-drawflow');
            for (var i = 0; i < elements.length; i++) {
              elements[i].addEventListener('touchend', this.drop, false);
              elements[i].addEventListener('touchmove', this.positionMobile, false);
              elements[i].addEventListener('touchstart', this.drag, false );
            }
           }
}
watch:{
      async activeWf(){
        if(this.activeWf!= '-1'){
          const data = await this.$http.$get('workflow/' + this.activeWf);
          this.activeDetails = data;      
          const container = this.$refs.drawflowContainer;
          this.editor = new Drawflow(container);
          const toImport = {
            "drawflow": {
              "Home": {
                "data": {
                  "1": {
                    "id": 1,
                    "name": "OriginalRepo",
                    "data": {},
                    "class": "personalized",
                    "html": "<div>Content</div>",
                    "typenode": false,
                    "inputs": {},
                    "outputs": {
                      "output_1": {
                        "connections": []
                      }
                    },
                    "pos_x": 259,
                    "pos_y": 174
                  }
                }
              }
            }
          }
          this.editor.start()
          this.editor.import(toImport); 
        }
      }
    },
jerosoler commented 8 months ago

In the "Watch" you don't have to do the "this.editor = new Drawflow(container);"

Try this:

watch:{
      async activeWf(){
        if(this.activeWf!= '-1'){
          const data = await this.$http.$get('workflow/' + this.activeWf);
          this.activeDetails = data;      
          //const container = this.$refs.drawflowContainer;
          //this.editor = new Drawflow(container);
          const toImport = {
            "drawflow": {
              "Home": {
                "data": {
                  "1": {
                    "id": 1,
                    "name": "OriginalRepo",
                    "data": {},
                    "class": "personalized",
                    "html": "<div>Content</div>",
                    "typenode": false,
                    "inputs": {},
                    "outputs": {
                      "output_1": {
                        "connections": []
                      }
                    },
                    "pos_x": 259,
                    "pos_y": 174
                  }
                }
              }
            }
          }
          //this.editor.start()
          this.editor.import(toImport); 
        }
      }
    },
JCPreethi commented 8 months ago

throws - Cannot set properties of null (setting 'innerHTML') error.

jerosoler commented 8 months ago

Can you provide a codepen or somewhere to test your code?

When you do a 'const data = editor.export();' Try also doing an 'editor.import(data)';

Does it show an error?

JCPreethi commented 8 months ago

No error when i do - When you do a 'const data = editor.export();' Try also doing an 'editor.import(data)'; The error only occurs when import using the data saved in database.

I'm setting up my code online, will post it here once done

JCPreethi commented 7 months ago

Hello @jerosoler, i found the issue, its because the object i saved in the sql server is in the front "{"drawflow":"Home":{}}". It is working with this - '{"drawflow":"Home":{}}' format.