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

Conditional Cases #13

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

Conditional Cases #13

wants to merge 4 commits into from

Conversation

atticoos
Copy link
Owner

@atticoos atticoos commented Jun 5, 2017

Seeking Feedback

I'd love to hear from some folks that currently use this, or are interested in using this, in what they think of the approaches behind these two new APIs.

Here we are -- support for multiple cases (#7):

If/ElseIf/Else

<div>
  {renderIf.if(x === 1) (
    <span>Hello, 1</span>
  ).elseIf(x === 2) (
    <span>Hello, 2</span>
  ).elseIf(x === 3) (
    () => <span>Hello, 3</span> // avoid evaluating if unsatisfied
  ).else(
    <span>Hello, {x}</span>
  ).evaluate()}
</div>

Instead of:

<span>
  {renderIf(x === 1) (
    <span>Hello, 1</span>
  )}
  {renderIf(x === 2) (
    <span>Hello, 2</span>
  )}
  {renderIf(x === 3) (
    () => <span>Hello, 3</span> // avoid evaluating if unsatisfied
  )}
  {renderIf(x !== 1 && x !== 2 && x !== 3) (
    <span>Hello, {x}</span>
  )}
</span>

Note: this does not remove renderIf - it's still quite handy and can be used for single conditions

Switch

<div>
  {renderIf.switch(x)
    .case(1) (
      <span>Hello, 1</span>
    )
    .case(2) (
      <span>Hello, 2</span>
    )
    .case(3) (
      () => <span>Hello, 3</span> // avoid evaluating if unsatisfied
    )
    .default(
      <span>Hello, {x}</span>
    )
    .evaluate()
  }
</div>

I'd love if we didn't have to call evaluate() - but I can't imagine it's possible to know when we're at the end of the execution chain.

Tests are still needed for this PR

@atticoos atticoos mentioned this pull request Jun 6, 2017
@stefensuhat
Copy link

stefensuhat commented Jun 7, 2017

will try this package after you merge this. 📦

@rstone770
Copy link

Hey @ajwhite. This looks pretty good to me.

If you want to get rid of evaluate why not just return the evaluate function with the api attached?

renderIf.switch(x)();

renderif.switch(x)
   .case(1)(<span>1</span>)
   .case(2)(<span>2</span>)
   .default(<span>default</span>)();

also i noticed that you are sorting conditions by 'type' before evaluating them, presumably because you'd like to make sure conditions are executed in the proper order. I think it might be better to enforce the behavior you want instead of fixing invalid usages of the library and causing potentially unexpected results. I think the easiest way to do this would be to follow a builder type approach and create a funnel.

Maybe something along these lines.

const multi = () => {
  const cases = [];
  
  function createEvaluator() {
    return function evaluate() {
      for (let index = 0; index < cases.length; index++) {
        if (cases[index].condition) {
          if (typeof cases[index].elemOrThunk === 'function') {
            return cases[index].elemOrThunk(); 
          }

          return cases[index].elemOrThunk;
        }
      }

      return null;
    };
  };
  
  function ifCondition (condition) {
    return (elemOrThunk) => {
      cases.push({ condition, elemOrThunk });
      return ifConditionApi;
    };
  };
  
  function elseCondition (elemOrThunk) {
    cases.push({ condition: true, elemOrThunk });
    return createEvaluator();
  };
  
  const ifConditionApi = Object.assign(
    createEvaluator(),
    {
      else: elseCondition,
      elseIf: ifCondition
    }
  );
 	
  return { if: ifCondition };
};

const renderIf = () => {};
renderIf.if = (condition) => multi().if(condition);

renderIf
  .if(false)('if condition')
  .elseIf(false)('else')
  .elseIf(false)('another else')
  .else('hello')();

renderIf
  .if(false)('if condition')
  .else('hi')();

renderIf
  .if(false)('if condition')
  .else('hi')
  .elseIf(true)('ERROR!!11!!one!')();

@JulianKingman
Copy link

Very handy, I like it! Any plans to merge?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants