0

I want to retrieve the data from two nodes when I connect them in reactflow App. I want to do this in the on connect function.

I currently have this function.

function Flow() {
  const [elements, setElements] = useState(initialNodes);
  const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
  const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
  const [isSidebarOpen, setIsSidebarOpen] = useState(true);
  //const getNodeDataById = (id: string | null) => {
  //  const node = elements.find((element) => element.id === id);
  //  return node?.data?.input || "No data found";
  //};
  const onConnect = useCallback(
    (params: Connection) => {
      // Extract the source and target node IDs from the connection parameters
      const { source, target }: string = params;

      // Retrieve node data based on the source and target node IDs from your state or data structure
      const sourceNodeData = nodes[source];
      const targetNodeData = nodes[target];

      // Log the node data to the console or perform any other operations as needed
      if (sourceNodeData && targetNodeData) {
        console.log('Source Node Data:', sourceNodeData);
        console.log('Target Node Data:', targetNodeData);
      }

      // Add the edge using the addEdge function from react-flow-renderer
      const updatedEdges = addEdge(params, edges);

      // Update the edges state with the newly created or modified edge data
      setEdges(updatedEdges);
    },
    [edges, setEdges]
  );

  const toggleSidebar = () => {
    setIsSidebarOpen(!isSidebarOpen);
  };

  const addNode = (nodeType: string) => {
    const newNode = {
      id: `dndnode_${nodes.length}`,
      type: nodeType,
      data: { label: `Node ${nodes.length + 1}` },
      position: { x: Math.random() * 400, y: Math.random() * 400 }, // Random position for demonstration
    };
    setNodes((nds) => [...nds, newNode]);
  };

  const exportToYAML = () => {
    const transformedNodes = nodes.map((node) => {
      // Extract only the desired data from each node
      const { id, data } = node;
      return { id, ...data };
    });

    const yamlContent = yaml.dump({ nodes: transformedNodes, edges });
    downloadYAML(yamlContent, "flow.yaml");
  };

  const updateNodeData = (nodeId: string, newData: any) => {
    setNodes((prevNodes) =>
      prevNodes.map((node) =>
        node.id === nodeId
          ? { ...node, data: { ...node.data, ...newData } }
          : node
      )
    );
  };

  const nodeTypes = useMemo(
    () => ({
      custom: CustomNode,
      initialDagNode: InitialDagNode,
      sftp: SftpToGcs,
      convert: (nodeProps: NodeProps) => (
        <ConvertDataFile
          {...nodeProps}
          updateNodeData={(newData) => updateNodeData(nodeProps.id, newData)}
        />
      ),
      // ... other node types ...
    }),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [
      /* dependencies, if any, such as updateNodeData */
    ]
  );

  return (
    <>
      <NodeSearch onAdd={addNode} />
      <div className="parent-container">
        <Sidebar
          onAddNode={addNode}
          isSidebarOpen={isSidebarOpen}
          toggleSidebar={toggleSidebar}
        />
        <div className={styles.flow}>
          <ReactFlow
            nodes={nodes}
            onNodesChange={onNodesChange}
            edges={edges}
            onEdgesChange={onEdgesChange}
            onConnect={onConnect}
            nodeTypes={nodeTypes}
            defaultEdgeOptions={defaultEdgeOptions}
            connectionLineType={ConnectionLineType.SmoothStep}
            fitView
          >
            <MiniMap />
            <Controls />
          </ReactFlow>
        </div>
        <button className={styles.yamlbutton} onClick={exportToYAML}>
          Export to YAML
        </button>
      </div>
    </>
  );
}

The issue im having is that the const { source, target } = params seems to be set as nulls and cant be used as indexes when looking through my node list. Has anyone encountered or solved this problem?

1
  • Doesn't it work when you use your getNodeDataById function? It seems like the problem is that you won't get the node by calling nodes[source]. But calling getNodeDataById(source) could work. You could also try to use getNode() from reactFlowInstance: reactflow.dev/api-reference/types/react-flow-instance#get-node Commented Jan 4, 2024 at 9:48

1 Answer 1

1

Params in onConnect event gives you something like this: enter image description here

In your case, node ids (source and target) will look like these: dndnode_0, dndnode_1 ....

Nodes is an array of objects but you are trying to access just by like an index with string type (dndnode_0 and dndnode_1). If you look into addNode block of your code, you are using id in a specific format and id is a property of each node object in Nodes array.

 const addNode = (nodeType: string) => {
    const newNode = {
      id: `dndnode_${nodes.length}`,
      type: nodeType,
      data: { label: `Node ${nodes.length + 1}` },
      position: { x: Math.random() * 400, y: Math.random() * 400 }, // Random position for demonstration
    };
    setNodes((nds) => [...nds, newNode]);
  };

So, you need to access something like this:

const sourceNodeData = nodes.find((node) => node.id === sourceParam);
const targetNodeData = nodes.find((node) => node.id === targetParam);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.