Search code examples
ember.jsember-cp-validations

cp-validation not working as expected


I am integrating the cp-validaiton with my ember app. but I am not getting any response. any one help me here.

my route js :

import Ember from 'ember';
import Validations from '../validation'

export default Ember.Route.extend(Validations, {
  num:null,
    message: '',
  model(){
    return { num:null}
  },
  actions:{ 
    check(){
        this.set('message','');

      this.validate().then(({model, validations})=>{
        if(validations.get('isValid')){
          console.log('statge', validations.get('isValid') )
                    this.set('message','');
                }else{
        if(model.get('validations.attrs.num.isInvalid')){
                        this.set('message',model.get('validations.attrs.num.messages'));
                    }
        }
      })
    }
  }
});

my validation.js :

import { validator, buildValidations } from 'ember-cp-validations';

export default buildValidations({
    num: [
        validator('number',{
        allowString: true,
        integer: true,
        message: 'Error! This is not an integer!'
}),
    validator('presence', true)
]
});

template :

<h1>This is my Route</h1>

Enter Age:<br>
{{input value=model.num}}<br>
<div style='color: red'>{{message}}<br></div>
<button {{action 'check'}}>Check</button><br>

Live in Twiddle


Solution

  • Validations must be defined upon the data object, which, in your case, is not the Route's attribute but the underlying Controller's model. Controller's model is set by Ember itself in setupControler() hook of the Route.

    Thus we use nested keys approach to target validations set upon correct data:

    import { validator, buildValidations } from 'ember-cp-validations';
    
    export default buildValidations({
        'controller.model.num': [
            validator('number',{
            allowString: true,
            integer: true,
            //message: 'Error! This is not an integer!'
    }),
        validator('presence', true)
    ]
    }); 
    

    Note: the attribute definition

    export default Ember.Route.extend(Validations, {
      num:null, // this is not used, just confusing :)
      message: '',
      ....
    }
    

    is unnecessary and confusing since not used, feel free to remove it.

    Checking validity / errors etc. on attribute basis can be achieved as follows:

     model.get('validations.attrs.controller.model.num.isValid');
     model.get('validations.attrs.controller.model.num.errors');
     model.get('validations.attrs.controller.model.num.messages');
    

    Your Route would look then like this:

    import Ember from 'ember';
    import Validations from '../validation'
    
    export default Ember.Route.extend(Validations, {
      model(){
        return { num:null}
      },
      actions:{ 
        check(){
            this.set('controller.message','');
    
          this.validate().then(({model, validations})=>{
            if(validations.get('isValid')){
               this.set('controller.message','');
            }else{
         if(model.get('validations.attrs.controller.model.num.isInvalid'){
                this.set(
                  'controller.message',
                   model.get('validations.attrs.controller.model.num.messages.firstObject'));
             }
            }
          })
        }
      }
    });
    

    However, I would strongly recommend migrating your validations-related code to the model instead of building them in the Route. It's more logical, readable, lets you decrease size of the code, and fits what you find in the ember-cp-validations docs.