Git Product home page Git Product logo

Comments (13)

gaperton avatar gaperton commented on September 4, 2024
       purchaseAmountEnabledLink.set(false);
       console.log(purchaseAmountEnabledLink.value);

When you set the link, link.value should not change. As it will change some upper state, and link object will be recreated. Links themselves are immutable.

However, this code behaves not according to the logic you described. Look at the inline comments:

if (!enabled) { <- when new link value is false...
       console.log("I am disabling thingy");
       purchaseAmountEnabledLink.set(false); <- ...you set another link to false. Should it be vice versa?
       console.log(purchaseAmountEnabledLink.value);  // <- that's remains 'true' as links are immutable.
    }

And onChange doesn't work with Input. It expects just valueLink or checkedLink.

from nestedlink.

gaperton avatar gaperton commented on September 4, 2024

Also, the behavior you described here seems to be close to the radio-buttons. There's an easier way to represent radio group state. In your case, just one boolean flag is enough.

https://github.com/Volicon/NestedLink#radio-groups-and-select-list

Also, there's another way of handling data cross-dependencies. You can apply pipe to the componentLink function, and handle cross-dependencies inside of pipe's argument. In this case, there will be just one atomic update of the state (and one render) on checkbox click.

https://github.com/Volicon/NestedLink#-linkpipe-transform--any--any---link

from nestedlink.

richard-engineering avatar richard-engineering commented on September 4, 2024

Ah yes, I copied the wrong code over into the issue, was cleaning up the code to remove unnecessary things (I initially misunderstood what the use case was my coworker was having problems with and thought it was on uncheck, that was copied from older code that equally didn't work). No it's not radio buttons, we actually want to allow multiple selections (there are more than 2 checkboxes on the actual screen, I simplified the code considerably in the issue).

from nestedlink.

richard-engineering avatar richard-engineering commented on September 4, 2024
When you set the link, link.value should not change. As it will change some upper state, and link object will be recreated. Links themselves are immutable.

How come this doesn't work then? Is it something with React not propagating a change down then?

  const firstEnabledLink = componentLink.at('first_checkbox_key').at('enabled')
   .onChange((enabled) => {
     console.log("I was hit", enabled);
     if (enabled) {
       console.log("I am disabling thingy");
       secondLink.set(false);
       console.log(secondLink.value);  // Remains 'true'
    }
  });
  ...
  <Input type='checkbox' checkedLink={firstEnabledLink}/>

Btw: thanks for the quick response
Edit: Fixed misnamed link variable in example, it was not misnamed when I tested it (blame my editing of the code to make the example clearer)

from nestedlink.

gaperton avatar gaperton commented on September 4, 2024

Here, when you disable first checkbox, you're disabling the second one instead of enabling it.

if (!enabled) { // <- this condition should be flipped, I guess
       console.log("I am disabling thingy");
       purchaseAmountEnabledLink.set(false);

from nestedlink.

gaperton avatar gaperton commented on September 4, 2024

Ok, about pipe. You could do it like this. Just do npm update.

function checkboxRules( next, prev ){
    if( next.first.enabled && !prev.first.enabled ){
         next.second = { enabled : false };
    }

   ...
   return next;
}

const smartLink = componentLink.pipe( checkboxRules );

So, all of your rules will be checked and applied in a single place, and you will have one atomic UI update no matter how complex they are. You have to detect what have changed manually, though. Comparing next and prev.

That's just an alternative approach to the problem when you move these rules checking upper. Must result in cleaner code. Which is way easier to reason about.

from nestedlink.

richard-engineering avatar richard-engineering commented on September 4, 2024

Ahh, saw your commit a few minutes ago. Is next the old state and prev the new state? I suppose I can console.dir that. I think I understand your example after staring at it, will test and get back to you with any questions.

from nestedlink.

gaperton avatar gaperton commented on September 4, 2024

next is new state, prev is prev state. Whatever you return substitutes the next state.

from nestedlink.

richard-engineering avatar richard-engineering commented on September 4, 2024

Okay I've implemented a test file and with pipe behaves very strangely with Input from 'valuelink/tags', I'll upload it to a project in a bit so you can run it yourself and see.

from nestedlink.

richard-engineering avatar richard-engineering commented on September 4, 2024

https://github.com/rhan-mentad/valuelink-debug

(sorry about the cruft, was getting weird path errors trying to port over a smaller webpack config we use so I gave up and used the original boilerplate project as the base)
Do npm i followed by npm start, navigate to localhost:3001.

Changes are in client/main.jsx

If you comment out the pipe command, the Input checkedLink functions fine. If the pipe command is in there then you cannot select the second checkbox after it gets deselected by clicking the first checkbox.

from nestedlink.

richard-engineering avatar richard-engineering commented on September 4, 2024

Nvm I think I was an idiot, mixed up old and new state in the callback. Everything works great for our use case. Thanks for the help :)

from nestedlink.

gaperton avatar gaperton commented on September 4, 2024

Okay, just for the case - I'm copying my fix to your example here:

function stateRules( next, prev ){ // first argument is new state, second - the previous one.
  if( next.second_checkbox_key.enabled && !prev.second_checkbox_key.enabled ){
    next.first_checkbox_key = { enabled : false };
  }

  if( next.first_checkbox_key.enabled && !prev.first_checkbox_key.enabled ){
    next.second_checkbox_key = { enabled : false };
  }

  return next;
}

And

const componentLink = Link.state(this, 'container').pipe( stateRules );

from nestedlink.

gaperton avatar gaperton commented on September 4, 2024

Yes, also:

  getInitialState: function () {
    return {
      container: {
        second_checkbox_key: {
          'enabled': false // Your initial state should be valid according to your rules.
        },
        first_checkbox_key: {
          'enabled': true
        }
      }
    }
  },

It works as you want. :)

from nestedlink.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.