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

Its possible to tell if the whole structure has been validated without errors? #90

Open
cloud-walker opened this issue Aug 4, 2017 · 11 comments

Comments

@cloud-walker
Copy link
Contributor

A function like allTheFieldOfTheNestedStructureAreTrue

I need to know if there is at least an error or not, to integrate spected with Formik

The formik hoc validate hook expect an empty object if the form has no errors, so I think to do something like

{
  validate: values => {
    const res = spected(validationSpecs, values)

    return isValid(res) ? ({}) : res
  }
}
@busypeoples
Copy link
Owner

Should work without too much work!

@busypeoples
Copy link
Owner

busypeoples commented Aug 4, 2017

The isValid has to be implemented in user land, as spected can't know how your data structure looks like. i.e. A successful data structure might look like the following:

{ name: true, nr: true }

or like this i.e.:

{ name: null, nr: null}

This is due to the fact that spected also offers the low level validate function which enables oto define own success and fail callbacks, see also API Docs

Here is an example showing how isValid could be implemented for a regular spected call.

import spected from 'spected'

const data = {
  nr: 6,
  name: 'foobar'
}

const spec = {
  nr: [[ nr => nr > 2, 'Nr has to be greater than 2' ]],
  name: [[ name => name.length > 4, 'Name has to be minimum lenght of 5!' ]]
}

const r1 = spected(spec, data)

const isValid = input => Object.values(input).filter(x => x !== true).length === 0 

// or functional...
// const isValid = R.compose(R.isEmpty, R.filter(x => x !== true), R.values)

console.log(r1, isValid(r1))

Also check the demo: http://jsbin.com/liragopide/edit?js,console,output

Also check the demo using the low level validate: http://jsbin.com/nisuyadecu/1/edit?js,console,output

@cloud-walker
Copy link
Contributor Author

cloud-walker commented Aug 4, 2017

Yes! I've already tought about that, btw my problem is that my form values structure is nested:

const values = {
  email: 'bruce.wayne@wayne.enterprise',
  posts: [
    {
      title: 'Learn functional programming the right way',
      body: 'lorem',
    },
    {
      title: 'How to become a better developer',
      body: 'lorem',
    },
  ],
}

So reading your source code, I think the best way to do it is an helper (?) that can take advantage of the same validationSpecs used on the normal spected function to return true / false

Like, I'm guessing here:

const values = {...}
const validationSpecs = {...}

isValid(validationSpecs, values) // true or false

The only problem is that I need now to run twice the algorithm, one for isValid and one for the actual validation output... mmmh!

@busypeoples
Copy link
Owner

busypeoples commented Aug 4, 2017

Nested shouldn't be a problem either.
Check isValid in the revalidation library. It works with nested structures.
https://github.com/25th-floor/revalidation/blob/master/src/utils/isValid.js

This is how revalidation calculates the valid state after validating with spected.
So I would pass the result returned from calling spected to the isValid function.

revalidation defines the success callback like this:

() => []

https://github.com/25th-floor/revalidation/blob/master/src/validate.js

So you might have to adapt the isValid function to check if true f.e.

@busypeoples
Copy link
Owner

If you need any help, let me know. I really like the idea of combing spected with Formik

@cloud-walker
Copy link
Contributor Author

No I think its ok, the only concern may be performance because I need first to run spected to generate the validation results, and then run a isValid function over it (so re-visiting the structure) over the validation results to determine if there is an error or not.

I continue to suspect that the spected validate function itself should return an errors count or true or false if validation is passed or not, like:

spected(validationSpecs, values)
/*
  The function above returns {
    valid: true | false,
    schema: {
       here the normal validation object of the spected library
    }
  }
  
  or {
    count: 0 or n errors counted during reduce,
    schema: {
       here the normal validation object of the spected library
    }
  }
*/

I can't imagine a better solution but it feels ugly... and also could be a breaking change..

@daniele-rapagnani
Copy link

Hey, what about something like this:

const specialSpected = (spec, input) => {
  let valid = true;
 
  const failFunc = (f) => {
    if (valid) {
      valid = false;
    }
    
    return f;
  };
  
 
  const validation = validate(() => true, failFunc, spec, input);
  
  return {
    valid,
    validation
  };
}

In this way you have no performance hit because you don't have to traverse the object again. I don't know if a solution like this should be provided by spected itself, I can't think of an elegant way to integrate it in the current API other than providing another function, which sounds like unnecessary complexity.

(demo: http://jsbin.com/coqodotuyo/edit?js,console,output)

@cloud-walker
Copy link
Contributor Author

I've sketched out a possible isValid function, here: http://jsbin.com/seworut/edit?js,output

For @daniele-rapagnani : I don't like to integrate the current idea either, but I still think it should be in the library, as its a common case, and I bet the most of the libraries out there will need it.

Cool trick BTW!

@busypeoples
Copy link
Owner

busypeoples commented Aug 4, 2017

@cloud-walker @daniele-rapagnani Thanks for the very valuable input!
I would rather avoid making isValid or valid a part of the API. I would rather like to see spected as a part of a pipeline. But I'll keep the issue open, maybe we can come up with a reasonable solution.

@cloud-walker
Copy link
Contributor Author

Sure! Maybe we can add refined version of the @daniele-rapagnani recipe on the future FAQ?

ref: #82

@busypeoples
Copy link
Owner

Yes, this would be really useful!

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

No branches or pull requests

3 participants