skip to Main Content

I need help with the async nature of Async storage and axios api. Here’s the functionality that I am trying to achieve ->

  1. send request to two separate api to get some data.

  2. display that data on the screen with some additional text

api request are authenticated so a token is passed as Authentication Header

I have attached the current implementation, I am having the a number of errors in this

Errors:

  1. Login_token not set in state after fetching from Async Storage.

  2. Data not set in state after api call

both resulting in either failed api calls or undefined state errors on render

This is my code.

import React, { FunctionComponent, useEffect, useCallback, useState} from 'react';
import { StyleSheet, View} from 'react-native';

// chat
import { GiftedChat } from 'react-native-gifted-chat';

// navigation
import { RootStackParamList } from '../../navigators/RootStack';
import { StackScreenProps } from '@react-navigation/stack';
export type Props = StackScreenProps<RootStackParamList, "Chat">;


// api 
import { Convo_details, Send_Msg, List_Msg, Expert_Public_Profile } from '../../api/UserApi';
import Spinner from 'react-native-loading-spinner-overlay';
import AsyncStorage from '@react-native-async-storage/async-storage';
import uuid from 'react-native-uuid';


const Chat: FunctionComponent<Props> = ({ navigation, route, ...props }) => {

    // console.log(props.route.params);
    const [login_token, setlogin_token] = useState('')
    const [conversation_id, setconversation_id] = useState('')
    const [conversation_details, setconversation_details] = useState({})
    const [currentuser, setcurrentuser] = useState({})
    const [loading, setLoading] = useState(false);
    const [expertuid, setexpertuid] = useState('')
    const [ExpertProfile, setExpertProfile] = useState({})
    const [messages, setMessages] = useState([]);


    useEffect(() => {
        getlogintoken()
        console.log("####################################","getlogintoken");
        
    }, [])
    /* conversationid */
    useEffect(() => {
        if (route.params != null) {
            setconversation_id(route.params[0])
        }
        console.log("####################################","conversation id");
    }, [])
    /* expert uid */
    useEffect(() => {
        if (route.params != null) {
            setexpertuid(route.params[1])
        }
        console.log("####################################","expert uid");
    }, [])
    /* expert public profile */
    useEffect(() => {
        getexpertpublicprofile()
        getConvo_details()
        console.log("####################################","convo_details");
    }, [])

    useEffect(() => {
        // get current user
        AsyncStorage.getItem("currentuser").then(res => {
            if (res != null) setcurrentuser(res)
            else alert("Current user not found")
        })
        console.log("####################################","current user");
    }, [])

    // set welcome msg
    useEffect(() => {
        if (Object.keys(conversation_details).length != 0 && Object.keys(ExpertProfile).length != 0)
            setwelcomemsg()
    }, [])

    const onSend = useCallback(async (messages = []) => {
        // console.log(messages[0].text);

        setMessages(previousMessages => GiftedChat.append(previousMessages, messages))
        const data = {
            conversation_id: "f98d6851-a713-4f58-9118-77a779ff175f",//conversation_id,
            message_type: "TEXT",
            body: messages[0].text
        }

        const res: any = await Send_Msg(data, login_token)
            .catch(error => {
                alert(`Send_Msg -> ${error}`)
                console.log(error);
                return
            })
        if (res.status == 200) {
            console.log(res.data);

        } else console.log(res);

    }, [])

    const getexpertpublicprofile = async () => {
        setLoading(true)
        const res: any = await Expert_Public_Profile(expertuid, login_token)
            .catch(error => {
                setLoading(false)
                console.log("Expert public profile ->");
                alert(`Expert public profile ->${error.message}`)
                console.log(error);
                return
            })
        setLoading(false)
        if (res.status === 200) setExpertProfile(res.data)
        else {
            alert(`get expert public profile${res.data.message}`)
            console.log("getexpertpublicprofile -->");
            console.log(res.data);
        }
    }

    const getlogintoken = () => {
        AsyncStorage.getItem("login_token").then(res => {
            if (res != null) {
                setLoading(false)
                setlogin_token(res)
            }
            else alert("No login token found")
        })
    }

    const getConvo_details = async () => {
        setLoading(true)
            const res: any = await Convo_details(conversation_id, login_token)
                .catch(error => {
                    setLoading(false)
                    alert(`Convo_details-->${error.message}`)
                    console.log("Convo_details -->");
                    console.log(error);
                    return
                })
            setLoading(false)
            if (res.status === 200) setconversation_details(res.data)
            else {
                alert(`get convo details-> ${res.data.message}`)
                console.log("getConvo_details -->");
                console.log(res.data);
            }
    }
    const setwelcomemsg = () => {
        try {
            let user = JSON.parse(currentuser)
            let messages = [
                {
                    _id: uuid.v4().toString(),
                    conversation_id: conversation_details.conversation_id,
                    created_at: new Date(),
                    from: conversation_details.recipient.user_uid,
                    type: "TEXT",

                    text: `About Me - ${ExpertProfile.bio}`,
                    user: {
                        _id: conversation_details.recipient.user_uid,
                    }
                },
                {
                    _id: uuid.v4().toString(),
                    conversation_id: conversation_details.conversation_id,
                    created_at: new Date(),
                    from: conversation_details.recipient.user_uid,
                    type: "TEXT",

                    text: `My name is ${conversation_details.recipient.name}`,
                    user: {
                        _id: conversation_details.recipient.user_uid,
                    }
                },
                {
                    _id: uuid.v4().toString(),
                    conversation_id: conversation_details.conversation_id,
                    created_at: new Date(),
                    from: conversation_details.recipient.user_uid,
                    type: "TEXT",
                    text: `Hi ${user.full_name}`,
                    user: {
                        _id: conversation_details.recipient.user_uid,
                    }
                }]
            setMessages(previousMessages => GiftedChat.append(previousMessages, messages))



        } catch (error) {
            console.log("try -> set welcome msg");
            console.log(error);
            return
        }
    }
    return (
        <View style={styles.maincontainer}>
            <Spinner
                visible={loading}
                textContent={'Loading...'}
                textStyle={{ color: '#FFF' }}
            />
            <GiftedChat
                messages={messages}
                onSend={messages => onSend(messages)}
                user={{
                    _id: currentuser.user_uid,
                }}
                isTyping={false}
                scrollToBottom={true}
                showAvatarForEveryMessage={true}
                renderAvatar={() => null}
            />
        </View>
    );
}

export default Chat;

const styles = StyleSheet.create({
    maincontainer: {
        flex: 1,
    },
});

2

Answers


  1. When axios returns, it usually give the response as res.data, so in your case, try either res.data or res.data.yourToken (I’m not sure how it’s your object).

    Login or Signup to reply.
  2. Gurav,
    As far as your code above, The api call’s will trigger even before you get currentuser or loginToken. You have to handle the api call after getting the currentuser and loginToken. This can be gracefully handled with async, await.

    example code:

        useEffect(() => {
            getData()
          }, [])
        
          useEffect(() => {
            if(login_token && currentuser) {
              //The api call goes here after you get the logintoken andcurrentuser. 
    // The above condition is just an example but will vary based on your requirements
            }
          }, [login_token, currentuser])
        
          const getData = async () => {
            await getlogintoken()
            await getcurrentuser()
          }
        
          const getlogintoken = async () => {
            await AsyncStorage.getItem("login_token").then(res => {
                    if (res != null) {
                        setLoading(false)
                        setlogin_token(res)
                    }
                    else alert("No login token found")
                })
          }
        
          const getcurrentuser = async () => {
             await  AsyncStorage.getItem("currentuser").then(res => {
                    if (res != null) setcurrentuser(res)
                    else alert("Current user not found")
                })
          }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search