Skip to content

Conditional Cases - #13

Open
atticoos wants to merge 4 commits into
masterfrom
conditional-cases
Open

Conditional Cases#13
atticoos wants to merge 4 commits into
masterfrom
conditional-cases

Conversation

@atticoos

@atticoos atticoos commented Jun 5, 2017

Copy link
Copy Markdown
Owner

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

stefensuhat commented Jun 7, 2017

Copy link
Copy Markdown

will try this package after you merge this. 📦

@rstone770

Copy link
Copy Markdown

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
Copy Markdown

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