patrick patrick - 5 months ago 204
Javascript Question

How to reference a prop when submitting redux-form

I have two models - contact and note. A note belongs to a contact.

I am trying to find a way to reference the contactId in the submit function.

I have passed contactId from a parent to the form:

// parent.js
<NoteNewForm contactId={contactId} onCancel={onCancelNewNoteClick}/>


In my form I want to use this in the
submit
function. I tried passing it as a param - i.e.
submit(contactId)
- but this does not work

const submit = (values, dispatch) => {
var noteData = Object.assign({}, values)

var primary = {
type: "notes",
attributes: noteData
}

// I want to use contactId instead of id: "1"
var relationships = {
contact: {
data: {
type: "contacts",
id: "1"
}
}
}

var params = createFormattedParams(primary, relationships)
dispatch(createNoteForContact(params))
}

export class NoteNewForm extends React.Component {
constructor(props) {
super(props)
this.getValidationState = this.getValidationState.bind(this)
}

getValidationState(isError = false, isTouched = false) {
if (isError && isTouched) {
return "error"
} else {
return null
}
}

render() {
const {fields: {subject, details, date}, handleSubmit, onCancel, contactId} = this.props
var extraProps = omit({...date}, 'value')
return (
<form onSubmit={handleSubmit(submit)} noValidate autoComplete="off">
<Row>
<Col xs={12} sm={6} smPush={6}>
<FormGroup controlId="date"
validationState={this.getValidationState(date.error, date.touched)}>
<ControlLabel>Date</ControlLabel>
<DateTimeField
inputProps={extraProps}
dateTime={date.value != "" ? date.value : moment().format('YYYY-MM-DD')}
format="YYYY-MM-DD" inputFormat="DD-MM-YYYY" mode="date"
onChange={value => date.onChange(value)}
maxDate={moment()}
/>
{date.touched && date.error &&
<HelpBlock>{date.error}</HelpBlock>
}
<FormControl.Feedback />
</FormGroup>
</Col>
<Col xs={12} sm={6} smPull={6}>
<FormGroup controlId="subjectText"
validationState={this.getValidationState(subject.error, subject.touched)}>
<ControlLabel>Subject</ControlLabel>
<FormControl type="text" {...subject}/>
{subject.touched && subject.error &&
<HelpBlock>{subject.error}</HelpBlock>
}
{!subject.error && !subject.value &&
<HelpBlock>Required</HelpBlock>
}
<FormControl.Feedback />
</FormGroup>
</Col>
</Row>
<Row>
<Col xs={12} sm={12}>
<FormGroup controlId="detailsText"
validationState={this.getValidationState(details.error, details.touched)}>
<ControlLabel>Details</ControlLabel>
<FormControl type="text" {...details}/>
{details.touched && details.error &&
<HelpBlock>{details.error}</HelpBlock>
}
{!details.error && !details.value &&
<HelpBlock>Required</HelpBlock>
}
<FormControl.Feedback />
</FormGroup>
</Col>
</Row>
<br/>
<Row>
<Col xs={12}>
<div className="pull-right">
<ButtonToolbar>
<Button type="submit" className="btn-accent">
Create
</Button>
<Button type="button" onClick={onCancel}>
Cancel
</Button>
</ButtonToolbar>
</div>
</Col>
</Row>
</form>
)
}
}

NoteNewForm = reduxForm({
form: 'NoteNewForm',
fields: ['subject', 'details', 'date'],
destroyOnUnmount: false,
validate
})(NoteNewForm)

export default NoteNewForm


I'm at a loss... Any ideas would be great.

Update! Solved below



I used the suggestion and link from skypecakes and this is the working code:

// the submit function
const submit = (values, dispatch, contactId) => {
var noteData = Object.assign({}, values)

var primary = {
type: "notes",
attributes: noteData
}

var relationships = {
contact: {
data: {
type: "contacts",
id: contactId
}
}
}

var params = createFormattedParams(primary, relationships)
dispatch(createNoteForContact(params))
}


In the form:

<form onSubmit={handleSubmit((values, dispatch) => {submit(values, dispatch, contactId)})} noValidate
autoComplete="off">

Answer

This question is explored in depth in the following question:

Redux-form handleSubmit: How to access store state?

Short answer: You can create a custom submit handler or use mergeprops. Custom submit handler seems cleaner. See the answer for how to use the custom submit handler.

You define your custom submit handler in mapDispatchToProps(), then call it like this:

<form onSubmit={ handleSubmit((values)=>{mySubmitHandler(values, this.props.user);}