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

Shared client and server side validation models #11

Closed
travisstaloch opened this issue Sep 17, 2017 · 7 comments
Closed

Shared client and server side validation models #11

travisstaloch opened this issue Sep 17, 2017 · 7 comments
Labels

Comments

@travisstaloch
Copy link

Thank you so much for sharing this great library!

Is it possible to share models between client and server? I'm working on a vue front end with a feathers/express back end where I want to have a single source of validation. In order to share models, should I just make a models folder in the project root directory (along side app and src directories which contain vue and feathers apps)? This project has a single package.json and webpack.config(s) at the project root directory.

I'm about to try this out. Can anyone provide any advice for getting this to work? I see that the vue-example has its models in the client src directory. Not sure if that app is doing server-side validation using those models. Is this the recommended method? I will post my results back here soon. Thank you.

@xpepermint
Copy link
Owner

Hey @travisstaloch. This package provides only a wrapper around RawmodelJS which adds VueJS reactivity to Model. Reactivity is only needed for reactive forms (reactive form validation). RawmodelJS works on the server and in the browser thus you can share your main logic between the server and the browser.

// client
import {ReactiveModel} from 'vue-rawmodel';
class User extends ReactiveModel {
  // main logic here
}

// server
import {Model} from 'rawmodel';
class User extends Model {
  // main logic here
}

@travisstaloch
Copy link
Author

travisstaloch commented Sep 17, 2017

Ok thanks. I didn't realize that its only a wrapper for reactivity.

Is it possible to put the validation logic in one place then like this?

class User extends ReactiveModel {
  constructor(data = {}) {
    defineValidations(this)
  }
}
class User extends Model {
  constructor(data = {}) {
    defineValidations(this)
  }
}

@xpepermint
Copy link
Owner

That should do the trick.

@travisstaloch
Copy link
Author

Is it possible to ignore a field defined in a model? I have SignupModel < ReactiveModel with fields email, password, and confirmPassword which shares validation definitions with SignupModelServer < Model as described above. I want to ignore the confirmPassword field on the server. Is there an easy way to achieve this?

@xpepermint
Copy link
Owner

Just have multiple models.

@travisstaloch
Copy link
Author

travisstaloch commented Sep 17, 2017

I was hoping to avoid that. I'm thinking I can use a condition() in the password2 validation which does some sort of check to switch it off, maybe check if typeof this !== 'SignupModelServer'

@travisstaloch
Copy link
Author

I think I found a solution: obj isInstanceOf ReactiveModel is more generic and can be reused in different models. Thought I would share to help out as it also shows a working defineValidator to compare with another field in the model which took a little bit of research to get working.

signup.js

import { ReactiveModel } from 'vue-rawmodel'
import { Model } from 'rawmodel'

export class SignupModel extends ReactiveModel {
  constructor(data = {}) {
    super(data)
    defineValidations(this, data)
  }
}

export class SignupModelServer extends Model {
  constructor(data = {}) {
    super(data)
    defineValidations(this, data)
  }
}

function defineValidations(that, data) {
  that.defineField('email', {
    type: 'String',
    validate: [
      {
        validator: 'presence',
        message: 'is required'
      },
      {
        validator: 'stringEmail',
        message: 'is invalid'
      }
    ]
  })

  that.defineField('password', {
    type: 'String',
    validate: [
      {
        validator: 'presence',
        message: 'is required'
      },
      {
        validator: 'stringLength',
        message: 'is too short or too long (%{min} to %{max} characters)',
        min: 4,
        max: 33
      }
    ]
  })

  that.defineValidator('equalsPassword', v => {
    return v === that.getField(['password']).value
  })

  that.defineField('password2', {
    type: 'String',
    validate: [
      {
        validator: 'presence',
        message: 'is required',
        condition() {
          return that instanceof ReactiveModel
        }
      },
      {
        validator: 'equalsPassword',
        message: 'is different from password',
        condition() {
          return that instanceof ReactiveModel
        }
      }
    ]
  })

  that.populate(data)
}

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

No branches or pull requests

2 participants