Instruction

We have a from:

render() {
    const {handleSubmit} = this.props;
    return (
        <form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
            <Field
                label="Title"
                name="title"
                component={this.renderField}
            />
            <Field
                label="Categories"
                name="categories"
                component={this.renderField}
            />
            <Field
                label="Post Content"
                name="content"
                component={this.renderField}
            />
            <button type="submit" className="btn btn-primary">Submit</button>
            <Link to="/" className="btn btn-danger">Cancel</Link>
        </form>
    );
}

We have a function that returns a field:

renderField(field) {
    const { meta: {touched, error} } = field;
    const className = `form-group ${touched && error ? 'has-danger' : ''}`;
    return (
        <div className={className}>
            <label>{field.label}</label>
            <input
                className="form-control"
                type="text"
                {...field.input}
            />
            <div className="text-help">
                {touched ? error : ''}
            </div>
        </div>
    );
};

We have a validation function:

function validate(values) {
    const errors = {};
    // Validation
    if (!values.title || values.title.length < 3) {
        errors.title = "Enter a title, that is at least 3 characters!!";
    }

    if (!values.categories) {
        errors.categories = 'Enter some categories';
    }

    if (!values.content) {
        errors.content = 'Enter some content please';
    }

    //IF errors is empty, the form is fine to submit
    //IF errors has *any* properties, redux form assumes form is invalid
    return errors;
}

But we still do not submit anything:

onSubmit(values) {
    console.log(values);
}

Now let's go to the action creator src/actions/index.js, and add new function:

import axios from 'axios'

export const FETCH_POSTS = 'fetch_posts';
export const CREATE_POST = 'create_post';

const ROOT_URL = 'http://reduxblog.herokuapp.com/api';
const API_KEY = '?key=ROOKA112';

...

export function createPost(values) {
    const request = axios.post(`${ROOT_URL}/posts${API_KEY}`, values);

    return {
        type: CREATE_POST,
        payload: request
    };
}

Now, let's return to our component. And import connect from react-redux:

import {connect} from 'react-redux'

Then import our new function:

import {createPost} from "../actions/index"

And now let's combine connect and reduxForm. It was:

export default reduxForm({
    validate,
    form: 'PostsNewForm'
})(PostsNew);

And after changes it's like:

export default reduxForm({
    validate,
    form: 'PostsNewForm'
})(
    connect(null, {createPost})(PostsNew)
);

Let's rewrite onSubmit:

onSubmit(values) {
    this.props.createPost(values);
}

Now we send data to the server, but we do not navigate anywhere.

To tell redux to navigate somwhere is easy, just add history.push("path") to it:

onSubmit(values) {
    this.props.history.push('/');
    this.props.createPost(values);
}

But we need to know, if post was created, and after that navigate somewhere.

So the first thing we should do is to pass the a callback function to the method, which submits data from UI:

onSubmit(values) {
    this.props.createPost(values, () => {
        this.props.history.push('/');
    });
}

Now, let's go to the action creator, and add promise to the function to call callback

export function createPost(values, callback) {
    const request = axios.post(`${ROOT_URL}/posts${API_KEY}`, values).then(() => callback());

    return {
        type: CREATE_POST,
        payload: request
    };
}

results matching ""

    No results matching ""