Search code examples
javascriptjqueryreactjsreduxformbuilder

How to call an action from inside an options object?


I am trying to implement this form builder into my react app. It has an option whereupon pressing the save button an onSave function, defined in options, is called. I want this function to call my existing addForm action that and then sends the form to the database to be saved however I am not sure how to properly call the action and pass it the form data it needs.

I have tried using a custom addForm method within the component but this made no difference.

Here is the code for the form builder component

import React, { Component, createRef } from 'react';
import { Container } from 'reactstrap';
import { addForm } from '../actions/formActions';
import { connect } from 'react-redux';
import $ from 'jquery';
import PropTypes from 'prop-types';

window.jQuery = $;
window.$ = $;

require('jquery-ui-sortable');
require('formBuilder');

class formSimplified extends Component {
    state = {
        name: '',
        data: []
    };

    options = {
        formData: [
            {
                type: 'header',
                subtype: 'h1',
                label: 'Test Form 1'
            }
        ],
        onSave: function(formData) {
            const newForm = {
                name: this.state.name,
                form: formData
            };

            // Add form via addForm action
            this.props.addForm(newForm);
        }
    };

    fb = createRef();
    componentDidMount() {
        $(this.fb.current).formBuilder(this.options);
    }

    static propTypes = {
        form: PropTypes.object.isRequired,
        isAuthenticated: PropTypes.bool
    };

    render() {
        return (
            <Container className="mb-5">
                <div id="fb-editor" className="form" ref={this.fb} />
            </Container>
        );
    }
}

const mapStateToProps = state => ({
    form: state.form,
    isAuthenticated: state.auth.isAuthenticated
});

export default connect(
    mapStateToProps,
    { addForm }
)(formSimplified);

And this is the addForm action in formActions.js

export const addForm = form => (dispatch, getState) => {
    axios
        .post('/api/forms', form, tokenConfig(getState))
        .then(res =>
            dispatch({
                type: ADD_FORM,
                payload: res.data
            })
        )
        .catch(err =>
            dispatch(returnErrors(err.response.data, err.response.status))
        );
    console.log('Saved Form');
};

The expected output would be a console log as per the action but the error I am getting is this:

TypeError: Cannot read property 'addForm' of undefined
onSave
/src/components/FormBuilder.js:91
  88 |         //$('.render-wrap').formRender({formData});
  89 |         //window.sessionStorage.setItem('formData', JSON.stringify(formData));
  90 |         // Save form using addForm;
> 91 |         this.props.addForm(formData);
  92 |     }
  93 |     //disableHTMLLabels: true,
  94 | };

Solution

  • You need to bind this.

    Simple way is use of arrow function,

    onSave: (formData) => {   //Auto binds `this`
                const newForm = {
                    name: this.state.name,
                    form: formData
                };
    
                // Add form via addForm action
                this.props.addForm(newForm);
            }