Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

After a backup and restore, problem to create new handles dynamically. #2078

Closed
remibesset opened this issue Apr 14, 2022 · 13 comments
Closed
Assignees
Milestone

Comments

@remibesset
Copy link

remibesset commented Apr 14, 2022

Describe the Bug

My project is to create a custom node, this custom node contains a button that allows new handles to be created.
This works fine, but when the flow is saved and restored, the new handles added to the same custom node are not connectable.

This error message appears until the node is deleted:

couldn't create edge for source handle id: dndnode_1649946748290_call_3_call_1649946788581; edge id: reactflow__edge-dndnode_1649946748290dndnode_1649946788581-dndnode_1649946778292

I already tried with this problem: #1641, but it did not solve my error, maybe I missed something

I noticed that the number of Handle I added and the number of handleBounds in the node are different after a restore, so I think this is a potential path to bug resolution. (You can see that on the screenshot)

Secondly, if a handle is removed, the edge remains and leads to errors, is it up to me to remove the edge programmatically?

react_flow_issue_handles_save_restore.mp4

0 -> 26 sec : The main issue
26 -> the end : The second question

Your Example Website or App

Here is the codesandbox link to my code, if you want to test it yourself:
https://codesandbox.io/s/react-flow-issue-add-handles-after-restoring-k4uwgg

Steps to Reproduce the Bug or Issue

  1. Go to the sandbox code link above
  2. Drag and drop a "Custom Node" and an "Output Node" (the sidebar is at the bottom of the stream).
  3. Click on the "+ Add" button to add handles, you can create as many handles as you want.
  4. Link the handles of the custom node with the output node, each handle does not need to be linked.
  5. After that save with the green button (download icon) in the upper right corner.
  6. Refresh the page with F5 or the container.
  7. You will see the correctly restored stream
  8. Now create a new handle or handles and try to connect them to the output source.

The bug occurs if you go to the console an error message appears every time you change the node.

If you try to delete or link the two nodes with the handles created before the restore, this works as it should.

Expected behavior

As a user I expected to add new handles to my custom node after a restore but I can't connect the new handles to nodes.

Screenshots or Videos

bug_resolution_track

Platform

  • OS: Linux
  • Browser: Chrome
  • Version: 10.1.0 & 10.0.8

Additional context

No response

@CasianoJr
Copy link

CasianoJr commented Apr 18, 2022

Hi, I encounter this same problem last week when upgrading to latest version.

My temporary fix was to exclude some keys that I may not need during nodes backup.

  const newNode = lodash.pick(node, [ "id", "sourcePosition", "targetPosition", "position",  "type", "data" ]);

@remibesset
Copy link
Author

Hi, I encounter this same problem last week when upgrading to latest version.

My temporary fix was to exclude some keys that I may not need during nodes backup.

  const newNode = lodash.pick(node, [ "id", "sourcePosition", "targetPosition", "position",  "type", "data" ]);

Hello, sorry for my late reply.

I have tried your fix, and it works very well for me, thank you very much.

I don't know when a final fix will arrive, but that's fine, I think I can close the issue.

@moklick
Copy link
Member

moklick commented May 28, 2022

Hey @remibesset! Thanks for the bug report. handleBounds will no longer be exposed to the client. Could you check if the latest version 10.3.4 fixes your issue?

@remibesset
Copy link
Author

Hey @moklick I just tested and everything is fine, I will continue to test further.
I think you can consider this issue as closed.

Hey @remibesset! Thanks for the bug report. handleBounds will no longer be exposed to the client. Could you check if the latest version 10.3.4 fixes your issue?

@stanislav-grin
Copy link

Hello @moklick,
I have used handleBounds for finding specific handle position. Now when it's removed, is there a way to get node's handles list and their positions? I could not find any issue or documentation pointing to this...

@remibesset
Copy link
Author

remibesset commented Jun 14, 2022

Hello @moklick, I have used handleBounds for finding specific handle position. Now when it's removed, is there a way to get node's handles list and their positions? I could not find any issue or documentation pointing to this...

Hi @stanislav-grin, you can retrieve this information by using the reactFlowInstance : https://reactflow.dev/docs/api/react-flow-instance/

The reactFlowInstance variable has a method where you can get your nodes:
reactFlowInstance?.getNodes()

You will be able to see a bunch of information and also the handleBounds:
image

@stanislav-grin
Copy link

Hi @remibesset, thank you for your answer!
But how can I pass the reactFlowInstance to the FloatingEdge component?
This component (FloatingEdge) is passing as in edgeTypes as prop into the ReactFlow component.
I also tried to use getNodes method from the useReactFlow hook, but there also no handleBound (they are hidden under the Symbol).

@remibesset
Copy link
Author

remibesset commented Jun 14, 2022

Hi @remibesset, thank you for your answer! But how can I pass the reactFlowInstance to the FloatingEdge component? This component (FloatingEdge) is passing as in edgeTypes as prop into the ReactFlow component. I also tried to use getNodes method from the useReactFlow hook, but there also no handleBound (they are hidden under the Symbol).

My bad, I have two different projects with react-flow which are not at the same version, and you are right we can't access to the handleBounds.

But like as you today I made some code and need handleBounds.

@moklick Could you make a method which we can get nodes with and without handleBounds ?
Or just fallback to the old commit and specify in doc to use this line :
const newNode = lodash.pick(node, [ "id", "sourcePosition", "targetPosition", "position", "type", "data" ]);
In the case of bad behavior on the front

@remibesset remibesset reopened this Jun 14, 2022
@stanislav-grin
Copy link

Just for information, I've also created a new topic in community discussions (before this discussion started here), with more information on this issue. Sorry for the accidental cross-posting.
#2218

@remibesset
Copy link
Author

remibesset commented Jun 14, 2022

So @stanislav-grin, after some research I find temporary fix which allow you to get back the handleBounds

    const nodesStore = useStore((state) => state.nodeInternals);
    const getNodeWithHandleBounds = useCallback(() => {
        const nodeWithHB: any = []
        nodesStore.forEach((node) => {
            const symboles = Object.getOwnPropertySymbols(node);
            const handleBounds = (node as any)[symboles[0]].handleBounds;
            const newNode = {
                ...node,
                handleBounds: handleBounds
            }
            nodeWithHB.push(newNode);
        })
        return nodeWithHB;
    }, [nodesStore])

For your specific case, I think that could work :

    const sourceNode = useStore(useCallback(store => {
        const node = store.nodeInternals.get(source);
        if (!node) return node;
        const symboles = Object.getOwnPropertySymbols(node);
        const handleBounds = (node as any)[symboles[0]].handleBounds;
        return {
            ...node,
            handleBounds
        }
    }, [source]))

@stanislav-grin
Copy link

Thank you, @remibesset, for your help and suggestion! It works perfectly.
Now this issue is not blocking me, though it would be better to have some kind of reliable documented API for this in the future.

@moklick
Copy link
Member

moklick commented Jun 15, 2022

Sorry guys! We will export the symbol you need for accessing the handleBounds!

@moklick moklick self-assigned this Jun 15, 2022
@moklick moklick added this to the 10.3.8 milestone Jun 16, 2022
@moklick
Copy link
Member

moklick commented Jun 22, 2022

you can now do:

import { internalsSymbol } from 'react-flow-renderer';

and then use it like:

const { handleBounds } = node[internalsSymbol];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Archived in project
Development

No branches or pull requests

4 participants