codeforboston / cliff-effects

Cliff effects guidance prototype (archived)
https://codeforboston.github.io/cliff-effects/#/
MIT License
30 stars 64 forks source link

More declarative way of choosing when to show a question #916

Open knod opened 6 years ago

knod commented 6 years ago

If we're considering a future where more programs are added, the logic of when to show a question could get really tangled. It might be useful if we could gather each question's requirements in one place. Current thought:

// aFile.js
allRequirements = {
  q1: function (client) {
    let passes = false;
    if (client.hasSection8
        && client.household[0].disabled
        && client.household[0].age > 60) {
      passes = true;
    }
    return passes;
  },
  // more requirements
};

Using the object, though, is a bit messy. At least, the ways I've come up with are. If needed, I'll put them in here.

dylanesque commented 6 years ago

If we're considering a future where more programs are added, the logic of when to show a question could get really tangled. It might be useful if we could gather each question's requirements in one place. Current thought:

// aFile.js
allRequirements = {
  q1: function (client) {
    let passes = false;
    if (client.hasSection8
        && client.household[0].disabled
        && client.household[0].age > 60) {
      passes = true;
    }
    return passes;
  },
  // more requirements
};

Using the object, though, is a bit messy. At least, the ways I've come up with are. If needed, I'll put them in here.

You're on the right track, I would suggest breaking off the logic that handles the boolean test in the if statement into a variable just to make it a bit cleaner.

knod commented 6 years ago

@dylanesque : As in this?

// aFile.js
allRequirements = {
  q1: function (client) {
    let passes = (client.hasSection8
        && client.household[0].disabled
        && client.household[0].age > 60);
    return passes;
  },
  // more requirements
};

Also, have any ideas of how to implement the use of this object?

knod commented 6 years ago

So one thing I've come up with that's cleaner in some ways, but more complicated in others. We have these requirements functions:

let reqs = { q1: function (client, formProps) {...}, ... };

Then we have an object which stores the state of the question, i.e. should we show it or not:

let reqsState = { q1: true, ... }

Then in the components, the questions use that object to decide whether to show themselves:

{ reqsState.q1 ? (
  <Q1>{ `Good ${timeOfDay}, ${client.name}` }</Q1>
) : (
  null
)}

// or

let q1 = null;
if ( reqsState.q1 ) {
  q1 = <Q1>{ `Good ${timeOfDay}, ${client.name}` }</Q1>
}
return (
  <Form>{ q1 }</Form>
);

And we update reqState when we update state, of course.

knod commented 6 years ago

Another option is to have the functions return components or null:

let getQuestions = {
  q1: function (client, otherData) {
    let passes = false;
    if (client.hasSection8
        && client.household[0].disabled
        && client.household[0].age > 60
        && otherData.hasMedicalExpenses) {
      passes = true;
    }

    if (passes) {
      return (<Q1>{ { `Good ${otherData.timeOfDay}, ${client.name}` } }</Q1>);
    } else {
      return null;
    }
  },
  // more functions
};

We'd use it like this:

<Form>{ getQuestions.q1(client, otherData) }</Form>

The problem here is that we don't get to see the components in their ecosystem and we have to pass around a lot more information. We might do that through Context, but it still seems like a bit of a juggling act.

knod commented 6 years ago

You don't really get to see what I mean about passing around props. Hmm. I'll edit that last one.

knod commented 6 years ago

Previous couple of comments edited, though I don't think those are great examples.

knod commented 5 years ago

Alternative option - each client property has a side-effects function. We could have an object keeping track of what questions are shown. The side-effects could be used to update the object.

knod commented 5 years ago

Btw, each State might need to be containing their own code for the form sections considering how different it can be per State. We can't know how much code really needs to be in each State, though, until we get some experts on hand. Add it to the wishlist!