question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Linked nodes aren't properly rendered when added manually

See original GitHub issue

I’m saving/loading node trees to a database, and everything is working except for linked nodes. When I use actions.addNodeTree to add a node that includes editable canvases, the content in those canvases is replaced by the default content specified in the UserComponent.

Using the example from the docs:

const Hero = ({background}) => {
  return (
    <div style={{ background }}>
      <Element is={Text} text="Hero Title" id="title_text" />
      <Element canvas is="section" id="droppable_container">
        <h2>I'm dropped here for now</h2>
      </Element>
    </div>
  )
}

If I were to manually add a node tree where the <h2> was replaced with some other content, it would instead load the <h2>I'm dropped here for now</h2> that’s defined above.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:8 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
prevwongcommented, Jul 15, 2020

@hdaggett Fixed in beta.9! 🥳

On another note, based on your example - I think we should probably introduce a helper function to allow developers to easily create a valid Node rather than having to manually create the object and ensuring all the necessary properties are there 😄

1reaction
hdaggettcommented, Sep 16, 2020

@Tashows You’ll want to serialize the nodes before saving, and then deserialize after saving and add the deserialized nodeTree to the ROOT node.

Serializing before saving

You might be able to do this with just query.getSerializedNodes(). In my case, I needed to separate into nodeTrees (because my ROOT node has multiple “pages” which can also be rendered independently).

Code for serializing multiple nodeTrees before saving (I call this from the Editor’s onNodesChange event, passing query)

getSerializedPageNodes = (query) => {
  // Get current nodes
  const allNodes = query.getSerializedNodes();
  const rootNode = query.node("ROOT").get();
  const pageNodes = rootNode.data.nodes;
  if (!pageNodes) return;
  const nodeArray = pageNodes.map((nodeId) => {
    const pageNode = query.node(nodeId);
    const pageNodeTree = pageNode.toNodeTree();
    const serializedNodes = nodesToSerializedNodes(
      pageNodeTree.nodes,
      allNodes
    );
    return {
      rootNodeId: nodeId,
      nodes: {
        [nodeId]: allNodes[nodeId],
        ...serializedNodes,
      },
    };
  });

  var pagesObject = {};
  pageNodes.forEach((nodeId, index) => {
    pagesObject[nodeId] = nodeArray[index];
  });
  return pagesObject;
};

// Helper: Replace Nodes with serializedNodes
const nodesToSerializedNodes = (nodes, allNodes) => {
  const serializedNodes = {};
  Object.keys(nodes).forEach((nodeId) => {
    serializedNodes[nodeId] = allNodes[nodeId];
  });
  return serializedNodes;
};

Deserializing after saving

Where serializedTree is a JSON tree as saved above and query is from the useEditor hook:

serializedTreeToNodeTree = (serializedTree, query) => {
  var nodeTree = { ...serializedTree };
  Object.keys(serializedTree.nodes).forEach((nodeId) => {
    nodeTree.nodes[nodeId] = query
      .parseSerializedNode(serializedTree.nodes[nodeId])
      .toNode((node) => (node.id = nodeId));
  });
  return nodeTree;
};

Add the nodeTree to the ROOT node:

actions.addNodeTree(pageNodeTree, "ROOT");

This took a lot of trial and error, and I haven’t updated Craft in a while so maybe there’s a better way. Hope this helps!

Read more comments on GitHub >

github_iconTop Results From Across the Web

React doesn't render on page refresh or manual URL entry
If I go to article page through this link, it will work fine but same link will not render anything if type it...
Read more >
Bypassing Nodes During Renders - Foundry Learn
0 is returned at render time, when the node is not being processed by the GUI. The standard way to add this into...
Read more >
How to Enable Server-Side Rendering for a React App
In this tutorial, you will initialize a React app using Create React App and then modify the project to enable server-side rendering.
Read more >
Linked Lists in Python: An Introduction - Real Python
That's because there is no specific end to a circular list. You can also see that choosing different starting nodes will render slightly...
Read more >
Adding child nodes through the 5-Press Setup Method - Linksys
Make sure you have a parent node connected to your modem or modem router with an internet ... Power ON all the child...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found