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.

Merge values from collector function into Node

See original GitHub issue

Is your feature request related to a problem? Please describe.

I want to use a value returned from useNode’s hook collector function in a canDrag rule, but since it’s available only in the hook’s returned object, I am forced to declare and run the calculations at multiple places.

Describe the solution you’d like

The values returned from useNode’s hook collector function are useful even outside of the components scope. It would be handy if they were merged into the Node itself.

const Hero = ({ title, ...rest }) => {
  const { connectors: { connect, drag }, setProp, tainted } = useNode(node => ({
    tainted: node.data.props.newTitle && title !== node.data.props.newTitle }
  }));
  return (
    <div>
      <h2>Edit me!</h2>
      <p contentEditable={true} onKeyUp={(e) => {
        setProp(props => {
          props.newTitle = e.target.innerText;
        })
      }}>{title}</p>
      <p style={{color: tainted ? 'black' : 'green'}}>{rest.newTitle}</p>
      <button ref={ref => connect(drag(ref))}>{tainted ? 'Drag me?' : "Don't touchme!"}</button>
    </div>
  )
}
Hero.craft = {
  defaultProps: {
    title: 'Sphinx of black quartz judge my vow!'
  },
  rules: {
    canDrag: node => node.data.someFittingPropertyName.tainted
  }
}

Additional context

At first I thought that node.data.custom might contain it, but it’s always empty.

image

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
prevwongcommented, Jan 16, 2020

This is similar to the Container and Card component in the Basic Tutorial.

const Hero = ({title}) => {
  // i 
  const { isSelected } = useNode((node) => ({ isSelected: node.events.selected }));
  return (
    <TextWrapper title={title}  heroIsSelected={isSelected} />
  )
}

const TextWrapper = ({title, heroIsSelected}) => {
   const { isSelected } = useNode((node) => ({ isSelected: node.events.selected }));
   
   // ii, Since TextWrapper is still under the same Node context as Hero, 
   // we have access to exact same Node as Hero
   const test = heroIsSelected == isSelected; // true

   return (
     ...
   )
}

Let’s say our TextWrapper component were to specify a slightly different collector function:

useNode(node => ({ isSelected: node.events.selected && node.events.dragged}))

Now, based on your proposal, if we were to save the collected values to the Node itself, the collected values in TextComponent will override the ones made by Hero

1reaction
prevwongcommented, Jan 16, 2020

Merging the collected values into the Node would not be ideal, since child components would share the same Node context, thus they would also be able to use the useNode hook and their collected values will be merged into the Node as well.

Instead, you could consider using custom values which is something like state values but for the Node itself. (I just realized I forgot to document how to use this, so thank you again! 🤣 🙈 )

Basically, like this:

const Hero = () => {
  // 1. get the custom value from the collector
  const { tainted, id  } = useNode(node => ({ 
   tainted: node.data.custom.tainted
  });

 // 2. get the setCustom action from the useEditor
 // p.s. I will probably add this action into the useNode() in one of the next releases 
 // so you don't have to get it from the useEditor() next time
  const { actions: {setCustom} } = useEditor();

 return (
  <a onClick={() => setCustom(id, custom => custom.tainted = !custom.tainted )}>
     Toggle Tainted 
   </a>
 );
}

Hero.craft = {
  custom : { 
    tainted: false
  },
 rules: {
    canDrag: (node) => !node.data.custom.tainted
 }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Node.js — How to Merge Objects - Future Studio
This tutorial shows you how to merge objects in JavaScript. ... Arrays; Promises; JSON; Iterators; Classes; Numbers; Objects; File System ...
Read more >
How to write the merge function for Collectors.toMap()
The 3rd argument to Collectors.toMap() is the merge function, which is a function that gets two values of the Map , and returns...
Read more >
Collectors toMap() method in Java with Examples
The task of the function is to merge the values having the same key in a way defined by the coder. This overloaded...
Read more >
Java - Combine Multiple Collections - Baeldung
A quick and practical guide to combining multiple collections in Java.
Read more >
composable streams/iterators · Issue #37729 · nodejs/node · GitHub
First, we have microtask-collector , which is similar to your WritableStreamToIterator class, but it allows external producers to add values to the current ......
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