Ling
Ling

Reputation: 911

How to use form input data as input for axios request in react native?

I need suggestion and help on how to use text from input form as the input for axios request in react native.

Right now I am adding a SignIn screen to my app. To retrieve any API for my app, there is a need for token. Before, I just made a one action file using redux to fetch token and store it inside a reducer.

For this case, I am trying to use email and password from form input while signing in as the data for me to retrieve the token. Long story short, this is my code SignInScreen.js right now

import React, { Component, AsyncStorage } from 'react';
import { View, Text } from 'react-native';
import { FormLabel, FormInput, Button, Card } from 'react-native-elements';
import axios from 'axios';
import { FETCH_TOKEN } from '../actions/types';
import apiConfig from '../services/api/url_config';

class SignInScreen extends Component {
    constructor(props) {
        super(props);
        this.state = {
            loggedIn: null,
            email: '',
            password: '',
            error: '',
            loading: false
        };
    }

onButtonPress = () => async (dispatch) => {
    let email = this.state.email;
    let password = this.state.password;

    AsyncStorage.getItem('auth', (res) => {
        let TOKEN_URL = apiConfig.url + 'tokens';
        let auth = {};

        if (res === null) {
            auth = {};
        } else {
            auth.push({
                email: email,
                password: password,
                role: 'user'
            });

            console.log(auth);

            axios.post(TOKEN_URL, auth)
            .then((response) => {
                console.log(response.data.token);
                dispatch({ type: FETCH_TOKEN, payload: response.data.token });
                this.props.navigation.navigate('Home');
            })
            .catch((e) => {
                console.log(e);
                this.props.navigation.navigate('SignIn');
            });
        }
    });    
}


render() {
    return (
        <View>
            <Card>
                <FormLabel>Email</FormLabel>
                <FormInput 
                    placeholder="[email protected]"
                    value={this.state.email}
                    onChangeText={email => this.setState({ email })}
                />
            </Card>
            <Card>
                <FormLabel>Password</FormLabel>
                <FormInput 
                    secureTextEntry
                    placeholder="password"
                    value={this.state.password}
                    onChangeText={password => this.setState({ password })}
                />
            </Card>

            <Card>
                <Button 
                    title="Log In"
                    onPress={this.onButtonPress}
                />
            </Card>

        </View>
    );
}

My actions/types

export const FETCH_TOKEN = 'fetch_token';

My tokenReducer.js

import {
    FETCH_TOKEN
} from '../actions/types';

export default function tokenReducer(state = '', action) {
    switch (action.type) {
        case FETCH_TOKEN:
            return action.payload;
        default:
            return state;
    }
}

I run this code and when I click on LogIn button, there is no result at all. Even the console log too also did not appear. I do not know how should I troubleshoot this problem if there is no console log I can refer to.

As you can see, to get the token, email and password, as well as the hardcoded value for 'role', need to be pass alongside the axios.post request. I am expecting if the request is successful, it will navigate the user to the Home screen while if it not, it will navigate the user to the SignIn screen again.

My question is, if I want to use the data or text from form input to be pass alongside axios request, am I on the right track with this code? If it not, please help me by sharing your suggestion.

Thank you.

Upvotes: 0

Views: 1548

Answers (1)

Dyo
Dyo

Reputation: 4464

Using fetch to replace your axios request :

fetch(TOKEN_URL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(auth),
  })
  .then(response => response.json())
  .then(responseData => /* responseData.token to access your token */ )
  .catch(err => /* Handle Error */ )
});

Maybe connect your component with redux to use this.props.dispatch to dispatch actions instead of asyn func :

import connect function from redux :

import { connect } from 'react-redux'

Add at the end of your file :

export default connect()(SignInScreen)

Remove async func :

onButtonPress = () => { 

use this.props.dispatch to dispatch actions :

this.props.dispatch({ type: FETCH_TOKEN, payload: response.data.token });

You can also get state from redux store in your component props by using mapStateToProps

function mapStateToProps(state) {
  return { isLoggedIn: state.isLoggedIn } // accessed by this.props.isLoggedIn in your component
}

export default connect(mapStateToProps)(SignInScreen)

Upvotes: 1

Related Questions