'Using React-Hook Form, How do I post data to my MongoDB in React Native

I am facing an issue where Im trying to post data to my mongoDB from the frontend using React Hooks on React Native. The problem is that Im struggling to get the values from the TextInput into an object that can be passed through the URL or storing the state of the TextInput value so I can pass through to API?

import {
  Text,
  SafeAreaView,
  View,
  TouchableOpacity,
  TextInput
} from 'react-native';
import React  from 'react';
import {useNavigation} from '@react-navigation/core';
import Toast from "react-native-toast-message";
import axios from "axios";
import { useForm, Controller } from "react-hook-form";

const EMAIL_REGEX = /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;

const SignUp = () => {

  const { control, watch, handleSubmit, formState: { errors } } = useForm({
    defaultValues: {
      emailAddress: '',
      password: '',
      confirmPassword: ''
    }
  });
  const password = watch('password');
  const navigation = useNavigation();

  const register = () => {
    
    let user = { email: email,  password: password };

    axios.post(`http://192.168.41.45:3001/register`, user).then((res) => {
      if (res.status == 200) {
        Toast.show({
            topOffset: 60,
            type: "success",
            text1: "Registration Succeeded",
            text2: "Please Login into your account",
          });
          setTimeout(() => {
            navigation.navigate('Login')
          }, 500);
        }
      }).catch((error) => {
        Toast.show({
          topOffset: 60,
          type: error,
          text1: "Something went wrong",
          text2: "Please try again",
      });
    });
  };
    
  return (
      <SafeAreaView style={{flex: 1, backgroundColor: '#fff'}}>
        <View style={{justifyContent: 'center', flex: 1}}>

            <View style={styles.input}>
              <Text style={styles.input}>
                  Register Account
            </Text>
            
            <View style={styles.input}>
                Complete your details to continue
              </Text> 
            </View>

          </View>

          <View style={styles.input}>
            <Controller
              name="email"
              control={control}
              rules={{
                required: 'Email is required',
                pattern: {value: EMAIL_REGEX, message: 'Email is invalid'},
              }} 
              render={({ field: { onChange, onBlur, value }, fieldState: {error} }) => (
                <TextInput
                  style={{height: 55,width: 330, padding: 15, alignItems: "center", borderRadius: 25, borderWidth: 2, margin: 12,
                          borderColor: error ? 'red' : 'black'}}
                  onChangeText={onChange}
                  onBlur={onBlur}
                  value={value}
                  placeholder="Enter your Email Address"
                  placeholderTextColor={'#000'}
                  underlineColorAndroid='transparent'
                  autoCompleteType='email'
                  keyboardType='email-address'
                  returnKeyType='next'
                  returnKeyLabel='next'
                />
              )}
            />
              {errors.emailAddress && <Text style={{color: 'red'}}>Email is required.</Text>}
          </View>

            <View style={styles.input}>
              <Controller
                name="password"
                control={control}
                rules={{
                  minLength: {value: 6, message: 'Password should be minimum 6 characters long'},
                  required: true,
                }} 
                render={({ field: { onChange, onBlur, value }, fieldState: {error} }) => (
                  <TextInput
                    style={{height: 55,width: 330, padding: 15, alignItems: "center", borderRadius: 25, borderWidth: 2, margin: 12, borderColor: error ? 'red' : 'black'}}
                    onChangeText={onChange}
                    onBlur={onBlur}
                    value={value}
                    placeholder="Enter your Password"
                    placeholderTextColor={'#000'}
                    autoCompleteType='password'
                    autoCapitalize='none'
                    returnKeyType='go'
                    returnKeyLabel='go'
                  />
                )}
              />
                {errors.password && <Text style={{color: 'red'}}>Password length is not strong.</Text>}
            </View>

            <View style={styles.input}>
              <Controller
                name="confirm-password"
                control={control}
                rules={{
                  minLength: {value: 6, message: 'Password should be minimum 6 characters long'},
                  required: true,
                  validate: value => value === password || 'Password do not match',
                }} 
                render={({ field: { onChange, onBlur, value }, fieldState: {error} }) => (
                  <TextInput
                    style={{height: 55,width: 330, padding: 15, alignItems: "center", borderRadius: 25, borderWidth: 2, margin: 12, borderColor: error ? 'red' : 'black'}}
                    onChangeText={onChange}
                    onBlur={onBlur}
                    value={value}
                    placeholder="Confirm your Password"
                    placeholderTextColor={'#000'}
                    autoCompleteType='password'
                    autoCapitalize='none'
                    returnKeyType='go'
                    returnKeyLabel='go'
                  />
                )}
              />
                {errors.confirmPassword && <Text style={{color: 'red'}}>Password length is not strong.</Text>}
            </View>


          <View style={styles.input}>
              <TouchableOpacity style={styles.input}
                  // onPress={() => navigation.navigate('MainTabNavigation')}
                  onPress={handleSubmit(register)}
              >
                <Text style={styles.button}>
                    Sign Up
                </Text>
              </TouchableOpacity>
          </View>

          <TouchableOpacity style={styles.input} onPress={() => navigation.navigate('SignIn')}>
                <Text style={styles.input}>
                    Already Have an Account? {""}
                    <Text style={{fontWeight: 'bold'}} >
                        Sign In
                    </Text>
                </Text>
          </TouchableOpacity>

        </View>
      </SafeAreaView>
  );
};

export default SignUp;



Solution 1:[1]

In register() You are not accepting the props passed in by handleSubmit(), those props are passed when you called handleSubmit(register), here is the code which you can just copy/paste

import {
  Text,
  SafeAreaView,
  View,
  TouchableOpacity,
  TextInput,
  StyleSheet,
} from 'react-native';
import React from 'react';
import {useNavigation} from '@react-navigation/core';
import Toast from 'react-native-toast-message';
import axios from 'axios';
import {useForm, Controller} from 'react-hook-form';

const EMAIL_REGEX =
  /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;

const SignUp = () => {
  const {
    control,
    watch,
    handleSubmit,
    formState: {errors},
  } = useForm({
    defaultValues: {
      emailAddress: '',
      password: '',
      confirmPassword: '',
    },
  });
  const password = watch('password');
  const navigation = useNavigation();

  const register = ({email, password}) => {
    let user = {email, password}; // because key: value are the same

    axios
      .post(`http://192.168.41.45:3001/register`, user)
      .then(res => {
        if (res.status == 200) {
          Toast.show({
            topOffset: 60,
            type: 'success',
            text1: 'Registration Succeeded',
            text2: 'Please Login into your account',
          });
          setTimeout(() => {
            navigation.navigate('Login');
          }, 500);
        }
      })
      .catch(error => {
        Toast.show({
          topOffset: 60,
          type: error,
          text1: 'Something went wrong',
          text2: 'Please try again',
        });
      });
  };

  return (
    <SafeAreaView style={{flex: 1, backgroundColor: '#fff'}}>
      <View style={{justifyContent: 'center', flex: 1}}>
        <View style={styles.input}>
          <Text style={styles.input}>Register Account</Text>

          <View style={styles.input}>
            <Text>Complete your details to continue</Text>
          </View>
        </View>
        {errors && console.log(errors)}

        <View style={styles.input}>
          <Controller
            name="email"
            control={control}
            rules={{
              required: 'Email is required',
              pattern: {value: EMAIL_REGEX, message: 'Email is invalid'},
            }}
            render={({
              field: {onChange, onBlur, value},
              fieldState: {error},
            }) => (
              <TextInput
                style={{
                  height: 55,
                  width: 330,
                  padding: 15,
                  alignItems: 'center',
                  borderRadius: 25,
                  borderWidth: 2,
                  margin: 12,
                  borderColor: error ? 'red' : 'black',
                }}
                onChangeText={onChange}
                onBlur={onBlur}
                value={value}
                placeholder="Enter your Email Address"
                placeholderTextColor={'#000'}
                underlineColorAndroid="transparent"
                autoCompleteType="email"
                keyboardType="email-address"
                returnKeyType="next"
                returnKeyLabel="next"
              />
            )}
          />
          {errors.emailAddress && (
            <Text style={{color: 'red'}}>Email is required.</Text>
          )}
        </View>

        <View style={styles.input}>
          <Controller
            name="password"
            control={control}
            rules={{
              minLength: {
                value: 6,
                message: 'Password should be minimum 6 characters long',
              },
              required: true,
            }}
            render={({
              field: {onChange, onBlur, value},
              fieldState: {error},
            }) => (
              <TextInput
                style={{
                  height: 55,
                  width: 330,
                  padding: 15,
                  alignItems: 'center',
                  borderRadius: 25,
                  borderWidth: 2,
                  margin: 12,
                  borderColor: error ? 'red' : 'black',
                }}
                onChangeText={onChange}
                onBlur={onBlur}
                value={value}
                placeholder="Enter your Password"
                placeholderTextColor={'#000'}
                autoCompleteType="password"
                autoCapitalize="none"
                returnKeyType="go"
                returnKeyLabel="go"
              />
            )}
          />
          {errors.password && (
            <Text style={{color: 'red'}}>Password length is not strong.</Text>
          )}
        </View>

        <View style={styles.input}>
          <Controller
            name="confirm-password"
            control={control}
            rules={{
              minLength: {
                value: 6,
                message: 'Password should be minimum 6 characters long',
              },
              required: true,
              validate: value => value === password || 'Password do not match',
            }}
            render={({
              field: {onChange, onBlur, value},
              fieldState: {error},
            }) => (
              <TextInput
                style={{
                  height: 55,
                  width: 330,
                  padding: 15,
                  alignItems: 'center',
                  borderRadius: 25,
                  borderWidth: 2,
                  margin: 12,
                  borderColor: error ? 'red' : 'black',
                }}
                onChangeText={onChange}
                onBlur={onBlur}
                value={value}
                placeholder="Confirm your Password"
                placeholderTextColor={'#000'}
                autoCompleteType="password"
                autoCapitalize="none"
                returnKeyType="go"
                returnKeyLabel="go"
              />
            )}
          />
          {errors.confirmPassword && (
            <Text style={{color: 'red'}}>Password length is not strong.</Text>
          )}
        </View>

        <View style={styles.input}>
          <TouchableOpacity
            style={styles.input}
            // onPress={() => navigation.navigate('MainTabNavigation')}
            onPress={handleSubmit(register)}>
            <Text style={styles.button}>Sign Up</Text>
          </TouchableOpacity>
        </View>

        <TouchableOpacity
          style={styles.input}
          onPress={() => navigation.navigate('SignIn')}>
          <Text style={styles.input}>
            Already Have an Account? {''}
            <Text style={{fontWeight: 'bold'}}>Sign In</Text>
          </Text>
        </TouchableOpacity>
      </View>
    </SafeAreaView>
  );
};

export default SignUp;

const styles = StyleSheet.create({
  input: {},
});

I hope that will help, happy coding. Greetings from Tanzania

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Raymond Michael