1

When I submit a form to my api, its weirdly only sending the last input that I filled out on the form. I have all of my form attributes saved to a const object and then sent with an axios post request. This is my first react native app, I don't know what's the cause of this issue. I have another form that doesn't have nested attributes, but saves without issue. How can I send all form inputs together in one api call with my nested form object?

SERVER LOGS

Started POST "/api/v1/applicant_forms" for 127.0.0.1 at 2021-05-02 13:08:14 -0400
Processing by Api::V1::ApplicantFormsController#create as JSON
  Parameters: {"applicant_form"=>{"user_id"=>"11", "personal_info_attributes"=>{"prefix"=>"Mr"}}}

ApplicantForm.js

handleSubmit(e) {
        e.preventDefault();
        const {applicant_form: {personal_info_attributes: {prefix, first_name}}, user_id} = this.state;
        const data_obj = {
          applicant_form: {
            user_id,
            personal_info_attributes: {
              prefix,
              first_name
            }
         }
        }
        const { navigation } = this.props;

        return axios({
          url: `http://127.0.0.1:3000/api/v1/applicant_forms`,
          method: 'POST',
          data: data_obj,
        }).then(response => {
          console.log("Successful Response" + response)
          navigation.navigate('home')  
        }).catch(err => {
          showMessage({
            message: "Something went wrong!",
            description: "Testing",
            type: 'danger'
          })
        })
      }


render() {
        return(
        <KeyboardAvoidingView behavior="padding">  
        <View style={{paddingVertical: 5, paddingHorizontal: 14}}>
         <View style={{backgroundColor: '#fff', width: Dimensions.get('window').width * 0.9, minHeight: 50, padding: 2, borderColor: 'gray', borderRadius: 4, borderWidth: 1, height: Dimensions.get('window').height * 0.8}}>
            <View style={styles.centerText}>
              <Text>Applicant Profile</Text>
            </View>
            <ScrollView>
              <Text>Prefix</Text>
              <FormInput   
              inputStyle={styles.input}
              autoCapitalize="none" 
              onSubmitEditing={() => this.applicant_form.personal_info_attributes.prefix} 
              autoCorrect={false} 
              keyboardType='default' 
              returnKeyType="next" 
              placeholder='Prefix: Mr. Mrs. Ms., etc'
              onChangeText={prefix => this.setState({ applicant_form: {personal_info_attributes: {prefix: prefix} }})}
             // value={this.state.applicant_form.personal_info_attributes.prefix} 
             />
                                 
             <Text>First Name</Text>
              <FormInput   
              inputStyle={styles.input}
              autoCapitalize="none" 
              onSubmitEditing={() => this.applicant_form.personal_info_attributes.first_name} 
              autoCorrect={false} 
              keyboardType='default' 
              returnKeyType="next" 
              placeholder='First Name'
              onChangeText={first_name => this.setState({ applicant_form: {personal_info_attributes: {first_name: first_name} }})}
             // value={this.state.applicant_form.personal_info_attributes.first_name} 
              />


<TouchableOpacity style={styles.saveButtoncontainer} onPress={e=>{this.handleSubmit(e)}}>
              <Text style={styles.buttontext}>Save Employment Profile</Text>
            </TouchableOpacity>
</View>
</View>
</KeyboardAvoidingView>
)
valcod3r
  • 321
  • 4
  • 14

1 Answers1

0

You are overwriting the applicant_form value every-time that a text field is edited.

The following code replaces the content in the state applicant_form to be {personal_info_attributes: {prefix: prefix} }. If you had set first_name before, it'll get removed.

<FormInput
  ...
  onChangeText={prefix => this.setState({ applicant_form: {personal_info_attributes: {prefix: prefix} }})}
/>

To prevent this overwriting the object, you can use the spread operator to make sure that the values are cloned and updated accordingly.

<FormInput
    onChangeText={prefix => 
        this.setState(prevState => ({
            applicant_form: {
                ...prevState.applicant_form,
                personal_info_attributes: {
                    ...prevState.applicant_form.personal_info_attributes,
                    prefix: prefix,
                }
            }
        }))
    }
/>

You can read more about this here: What's the best alternative to update nested React state property with setState()?

nipuna-g
  • 6,252
  • 3
  • 31
  • 48