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

[Question] Return custom error message from onSubmit #161

Closed
cyclops24 opened this issue Jan 5, 2017 · 6 comments
Closed

[Question] Return custom error message from onSubmit #161

cyclops24 opened this issue Jan 5, 2017 · 6 comments
Assignees
Labels
Type: Bug Bug reports and their fixes

Comments

@cyclops24
Copy link

cyclops24 commented Jan 5, 2017

Hi @radekmie ,
I'm try to create a simple login form with Uniforms, SimpleSchema2 and Meteor.

This is my schema:

import SimpleSchema from 'simpl-schema';

const LoginSchema = new SimpleSchema({
    email: {
        label: "Email Address",
        type: String,
        uniforms: {
            placeholder: "Please enter your email..."
        }
    },
    password: {
        label: "Password",
        type: String,
        uniforms: {
            type: "password",
            placeholder: "Please enter your password..."
        }
    }
});

export default LoginSchema;

And this is my form component:

import { Meteor } from 'meteor/meteor';
import React, { Component } from  'react';
import AutoForm from 'uniforms-bootstrap3/AutoForm';
import {SubmitField} from 'uniforms-bootstrap3';
import LoginSchema from '../../api/users/loginSchema.js';
import { browserHistory, Link } from 'react-router'

export default class LoginForm extends Component {
    constructor(props){
        super(props);
        this.state = {
            loginError: ''
        };
        this.handleLoginSubmit = this.handleLoginSubmit.bind(this);
    }

    handleLoginSubmit(doc) {
        console.log(JSON.stringify(doc));
        Meteor.loginWithPassword(doc.email, doc.password, (err) => {
// login error
            if (err)
            {
                console.warn("error");
                console.warn(JSON.stringify(err));
                if(err.reason == "User not found"){
                    this.setState({loginError: "User not found, you can sign up for this username."});
                    return false;
                }
                if(err.reason == "Incorrect password"){
                    this.setState({loginError: "Your password is incorrect. Please enter again!"});
                    return false;
                }
                if(err.message == "User has no password set [403]")
                {
                    this.setState({loginError:  "Please contact your system administration!"});
                    return false;
                }

                else {
                    this.setState({loginError: err.message});
                    return false;
                }
            }
// login success
            else {
                browserHistory.push('/dashboard');
            }
        });
    };
    
   render(){
       const CustomSubmitField = props =>
               <SubmitField value="Login" />;

        return (
            <div>
                <AutoForm schema={LoginSchema} placeholder={true}
                          submitField={CustomSubmitField}
                          onSubmit={this.handleLoginSubmit}>
                </AutoForm>
                <p className="account-form-text-after" id="forgot-password-link">
                    Forget password?
                    <Link to="/sign-up">
                        Click here!
                    </Link>
                </p>
            </div>
        )
    }
}

I'm using this.setState({loginError: "error message"}); now but I think using onSubmitSuccess and onSubmitFailure is simpler approach and also it's better because I think with this two props I can show error message on form validation error box like other error (Required and ...)
I read #51 and https://github.com/vazco/uniforms/blob/master/API.md but can't understand how change my code for using promise.
Can you help me?

@radekmie radekmie self-assigned this Jan 5, 2017
@radekmie radekmie added the Type: Question Questions and other discussions label Jan 5, 2017
@radekmie
Copy link
Contributor

radekmie commented Jan 5, 2017

Hey @cyclops24!

Answer 0:
If you want to display login error in the same way as a validation error, use error prop on your form - documentation is here and examples are below.

Answer 1 (if you want to use onSubmitFailure and onSubmitSuccess):

class LoginForm extends Component {
    constructor () {
        super(...arguments);

        this.state = {
            loginError: null
        };

        this.onSubmit        = this.onSubmit.bind(this);
        this.onSubmitFailure = this.onSubmitFailure.bind(this);
        this.onSubmitSuccess = this.onSubmitSuccess.bind(this);
    }

    onSubmit ({email, password}) {
        return new Promise((resolve, reject) =>
            Meteor.loginWithPassword(email, password, error =>
                error ? reject(error) : resolve()
            )
        );
    }

    onSubmitFailure (error) {
        // This error should be an Error instance with correct message, error
        // recognised by your schema or a string.
        this.setState({loginError: error});
    }

    onSubmitSuccess () {
        browserHistory.push('/dashboard');
    }

    render () {
        return (
            <div>
                <AutoForm 
                    error={this.state.loginError}
                    onSubmit={this.onSubmit}
                    onSubmitFailure={this.onSubmitFailure}
                    onSubmitSuccess={this.onSubmitSuccess}
                    placeholder
                    schema={LoginSchema} 
                    submitField={CustomSubmitField}
                />

                <p className="account-form-text-after" id="forgot-password-link">
                    Forget password?
                    <Link to="/sign-up">
                        Click here!
                    </Link>
                </p>
            </div>
        )
    }
}

Answer 2 (if you don't want to use onSubmitFailure and onSubmitSuccess):

// Change 1
<AutoForm 
    error={this.state.loginError}
    onSubmit={this.onSubmit}
    onSubmitFailure={this.onSubmitFailure}
    onSubmitSuccess={this.onSubmitSuccess}
    placeholder
    schema={LoginSchema} 
    submitField={CustomSubmitField}
/>
// into
<AutoForm 
    error={this.state.loginError}
    onSubmit={this.onSubmit}
    placeholder
    schema={LoginSchema} 
    submitField={CustomSubmitField}
/>

// Change 2
return new Promise((resolve, reject) =>
    Meteor.loginWithPassword(email, password, error =>
        error ? reject(error) : resolve()
    )
);
// into
return new Promise((resolve, reject) =>
    Meteor.loginWithPassword(email, password, error =>
        error ? reject(error) : resolve()
    ).then(this.onSubmitSuccess, this.onSubmitFailure);
);

And that's it.

Side note 1:
You should pass props your <CustomSubmitField /> received down to <SubmitField />.

Side note 2:
You shouldn't create a new component in the render method.

@cyclops24
Copy link
Author

Thanks @radekmie ,
I test Answer 1 and seems it's working but it has small issue. When I enter wrong username and password and submit form submit button changed to disable and I can't try login with new username and password. It's also print many promise error on console for each key when I type in login form after error like this:
uniform_login


I'm going to start new open source example and reproduce it.
I think login and sign-up form with uniform and simple schema can useful for others to 😉
I post example repo link to #158 too.

@radekmie
Copy link
Contributor

radekmie commented Jan 6, 2017

Yes, I forgot about it - you should also reset this error after change... It's like this, because your form always have an error - that one from first login try.


Which version are you using? Also, which browser? There is a silencer for these errors, but I can't recall, when it was introduced.

@cyclops24
Copy link
Author

@radekmie I reproduce this here: https://github.com/MeteorDemoApps/Uniforms-UserAccount-demo
Can you see it man?

@radekmie
Copy link
Contributor

radekmie commented Jan 6, 2017

Yep, that was both problem in uniforms and in your form. I'll publish fix in a second and submit a PR in your demo.

@radekmie radekmie added Type: Bug Bug reports and their fixes and removed Type: Question Questions and other discussions labels Jan 6, 2017
@cyclops24
Copy link
Author

@radekmie Thanks man. It's fixed now. 😉

@radekmie radekmie moved this to Closed in Open Source Nov 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug Bug reports and their fixes
Projects
Archived in project
Development

No branches or pull requests

2 participants