These are chat archives for jdubray/sam

4th
Feb 2018
Scott Conklin
@srconklin
Feb 04 2018 18:09
still keep coming back to our last discussion on validation.. I see a similar pattern evolving regarding "page wait spinners".. I keep a pageWait : false on my model that is flipped to true and presented to the model while waiting for an Ajax server side call to complete which shows the spinner when the view renders.. I then set it back to false in NAP().
Is this a bad approach? am I polluting my model with non-domain flags with logic control flags that might be handled in a different approach?
Jean-Jacques Dubray
@jdubray
Feb 04 2018 20:06
@srconklin another way to do it is to start the spinner in the view component when you need it and turn it off once the model has mutated and rendered. This is a bit cheating, but that is really coming from the non-functional nature of some HTML corners.
Jean-Jacques Dubray
@jdubray
Feb 04 2018 20:19
@srconklin to go back to the form validation question, let's take this free sample as an example.
The form supports validation:
image.png
Jean-Jacques Dubray
@jdubray
Feb 04 2018 20:27
I typically create a view component that looks like this:
validation( params ) {
        let hasErrors = params.hasErrors
        return `
        <form class="container ${hasErrors ? `was-validated`: ``}" id="needs-validation" novalidate="">
            <div class="row">
                <div class="col-md-6 mb-3">
                    <label for="validationCustom01">First name</label>
                    <input type="text" class="form-control" id="validationCustom01" placeholder="First name" value="Mark" required="">
                </div>
                <div class="col-md-6 mb-3">
                    <label for="validationCustom02">Last name</label>
                    <input type="text" class="form-control" id="validationCustom02" placeholder="Last name" value="Otto" required="">
                </div>
            </div>
            <div class="row">
                <div class="col-md-6 mb-3">
                    <label for="validationCustom03">City</label>
                    <input type="text" class="form-control" id="validationCustom03" placeholder="City" required="">
                    ${ (hasErrors && !params.city) ? `<div class="invalid-feedback">Please provide a valid city.</div>` : ``}
                </div>
                <div class="col-md-3 mb-3">
                    <label for="validationCustom04">State</label>
                    <input type="text" class="form-control" id="validationCustom04" placeholder="State" required="">
                    ${ (hasErrors && !params.state) ? `<div class="invalid-feedback">Please provide a valid state.</div>` : ``}
                </div>
                <div class="col-md-3 mb-3">
                    <label for="validationCustom05">Zip</label>
                    <input type="text" class="form-control" id="validationCustom05" placeholder="Zip" required="">
                    ${ (hasErrors && !params.zip) ? `<div class="invalid-feedback">Please provide a valid zip.</div>`: ``}
                </div>
            </div>
            <button class="btn btn-primary" type="submit">Submit form</button>
        </form>`
    }
I always try to reduce it to V = f(M)
This also works for modal. Modals can be made to appear (in a functional way) with a simple attribute turned on or off.
Entaro Adun
@_entaroadun_twitter
Feb 04 2018 21:39
Q
Scott Conklin
@srconklin
Feb 04 2018 21:42
@jdubray Thanks. So, introducing a hasErrors in the model is sort of the approach I am following. I guess I was just allowing the invalid form data to be stored in the model for the purposes of displaying it back to the user... I think I am at least going in the right direction.
Scott Conklin
@srconklin
Feb 04 2018 21:58
@jdubray And where do you empty out or reset hasErrors?
Jean-Jacques Dubray
@jdubray
Feb 04 2018 23:42
@srconklin In general that can be done in the State function, this is a computed value (not a mutation per se). The model is just property/values with mutation rules (which include some data integrity), for instance the model would still accept partial values from the form, it would not violate any mutation rule. hasErrors could be a general aggregate that would be true when there is an error in any form.
From a purist perspective, !params.city should not be something the view knows about since that's application logic, not view logic.
Another type of validation could happen in the action where you validate that the city, state and the zip code match. So you'll call an API that will give you that answer and the proposal to the model could be an exception.
The View component could be implemented like:
<div class="col-md-3 mb-3">
           <label for="validationCustom05">Zip</label>
           <input type="text" class="form-control" id="validationCustom05" placeholder="Zip" required="">
           ${ (hasErrors && !params.zip) ? `<div class="invalid-feedback">Please provide a valid zip.</div>`: ``}
           ${ (hasErrors && !params.invalidZip) ? `<div class="invalid-feedback">Zip code does not match city/state</div>`: ``}
</div>
But overall, the rule would be:
  • no rules in the view components (!params.zip ~ok)
  • input validation in the action
  • mutation validation in the model
  • "state" errors, mutations was successful, but the property values are in invalid state (computed only as a pure function of the model)