title: Validate string length and make sure it contains certain characters in React Redux Form
body: <p>Working on a <code>set_password.js</code> component that, you guessed it, lets the user set their password. It has them enter it twice to make sure they match. The password should have the criteria that it is at least 8 characters in length, has one uppercase, has one number, has one special character. Nothing ground breaking.</p>
  
  <p>I know how to validate this stuff server side, but would rather validate it client side so the user doesn't have to wait for server response. I am struggling with how to do it.</p>
  
  <p>I have a <code>validate</code> function that takes the values from the fields and validates them.</p>
  
  <pre><code>function validate(values) {
      const errors = {};
  
      if (!values.password1) {
          errors.password1 = 'This field cannot be empty.'
      }
      if (!values.password2) {
          errors.password2 = 'This field cannot be empty.'
      }
      if (values.password1.length &lt; 8) {
           errors.password1 = 'The password provided is not long enough.'
      }
      if (values.password2.length &lt; 8) {
           errors.password2 = 'The password provided is not long enough.'
      }
      return errors
  }
  </code></pre>
  
  <p>This is all I have so far, and I get an error <code>Cannot read property 'length' of undefined</code>, so I am apparently putting this logic in the wrong area.</p>
  
  <p>I'm starting to think that I should put it in the action so it is validated only after the user does <code>onSubmit</code>. I guess it would look something like:</p>
  
  <pre><code>onSubmit(values) {
      this.props.setPassword(values, this.props.match.params);  
  }
  </code></pre>
  
  <hr>
  
  <pre><code>export function setPassword({ password1, password2 }, { id, key }) {
      return function(dispatch) {
          if (password1.length &lt; 8 &amp;&amp; password2.length &lt; 8) {
              axios
                  .post(
                      `${ROOT_URL}/api/auth/set_password/`, 
                      { password1, password2, id, key }
                  )
                  .then(response =&gt; {
                      console.log('Password changed')
                  })
                  .catch(error =&gt; {        
                      dispatch(authError(error.response.data.non_field_errors[0]));
          });
          }
  
      }
  }
  </code></pre>
  
  <p>Anyway, so what is the correct way to accomplish this? Checking length of string, that it has at least one uppercase letter, that is has one special character, and one number?</p>
  
  <p>EDIT:</p>
  
  <p>Relevant form data:</p>
  
  <pre><code>// This renders errors regarding the form inputs
      renderField(field) {
          const { 
              label, 
              type,
              name,
              meta: {
                  touched, 
                  error 
              } 
          } = field;
  
          return (
              &lt;div className='form-group'&gt;
                  &lt;label&gt;{label}&lt;/label&gt;
                  &lt;input 
                      className='form-control' 
                      type={type}
                      placeholder={label}
                      {...field.input} 
                  /&gt;
                  &lt;div className='text-danger'&gt;
                      {touched ? error : ""}
                  &lt;/div&gt;
              &lt;/div&gt;
          );
      }
  
      // The main body to be rendered
      render() {
          if (this.props.permitRender) {
              const { handleSubmit } = this.props;
              return (
                  &lt;div&gt;
  
                      &lt;h3&gt;Set New Password&lt;/h3&gt;
                      &lt;p&gt;Type your new password twice. &lt;/p&gt;
                      &lt;p&gt;It must be a minimum of 8 characters in length and contain at least:&lt;/p&gt;
                      &lt;ol&gt;
                          &lt;li&gt;One uppercase character&lt;/li&gt;
                          &lt;li&gt;One special character&lt;/li&gt;
                          &lt;li&gt;One number&lt;/li&gt;
                      &lt;/ol&gt;
  
                      &lt;form onSubmit={handleSubmit(this.onSubmit.bind(this))}&gt;
                          {this.renderAlert()}
                          &lt;Field 
                              label='Enter New Password'
                              name='password1'
                              type='password'
                              component={this.renderField} 
                          /&gt;
                          &lt;Field 
                              label='Confirm New Password'
                              name='password2'
                              type='password'
                              component={this.renderField} 
                          /&gt;
                          &lt;button type="submit" className="btn btn-primary"&gt;Submit&lt;/button&gt;
                      &lt;/form&gt;
                  &lt;/div&gt;
              );            
          } else if (!this.props.permitRender) {
              return ( 
                  &lt;div&gt; { this.renderAlert() } &lt;/div&gt;
              );
          } 
      }
  </code></pre>