can't set response from api to messages array of GiftedChat

Viewed 765

I am new to react native. I am currently developing a messaging app.

I have used npm-giftedChat for UI & functionalities. The problem is I need to get the response from api & set it to the messages array of giftedchat. I receive data from API and while I set it to messages array it loops over data and renders only the last data in that array.

Any help would be appreciated.I have added my code here

Please find where I am going wrong?

    componentWillMount() {
            var arrMsg = [];
            var data = params.data
            for(let i = 0; i < data.Replies.length ; i++){
     var obj =     {
                                  _id: data.To._id,
                                  text: data.Replies[i].Reply,
                                  createdAt: data.Replies[i].CreatedDate,
                                  user: {
                                      _id: data.From._id,
                                      name: 'React Native',
                                      avatar: data.From.Profile.DisplayPicture
                                  },
                                  image: '',
                              }
                            arrMsg.push(obj)
              }
              this.setState({messages: arrMsg})
}

Sample output

sample output

2 Answers

My self also facing same issues..

setting is very important in gifted chat..

so try to use following in ur code,i have edited same like your code.if any queries let me know thanks.

for (let i = 0; i < data.Replies.length; i++) {
            console.log(data.Replies[i].CreatedDate);
            debugger

            var id = data.From._id

            if (data.To.id == UserID) {
                id = this.state.userID
            }

            const obj = {
                _id: Math.round(Math.random() * 1000000),
                text: data.Replies[i].Reply,
                createdAt: data.Replies[i].CreatedDate,
                user: {
                    _id: id,
                    name: 'React Native',
                    avatar: data.From.Profile.DisplayPicture
                },
                image: '',

            }
            arrMsg.push(obj);

        };


        this.setState((previousState) => {
            return {
                messages: GiftedChat.append(previousState.messages, arrMsg)
            };
        });

I wrote a gist here on how to add a web socket listening to a rails channel to a react native chat screen + Gifted Chat

// chat.js
import React, { Component } from 'react';
import {
    Text,
    View,
    StyleSheet,
    TouchableHighlight,
    Dimensions,
    AppState,
    AsyncStorage,
    Alert
} from 'react-native';
import {
    GiftedChat,
    Actions,
    Bubble,
    SystemMessage
} from 'react-native-gifted-chat';
import axios from 'axios';
import ActionCable from 'react-native-actioncable';
import { yourRootUrl, websocketUrl } from '../config/constants';

class Chat extends Component {
    state = { 
        messages: [],
        client: '',
        accessToken: '',
        expiry: '',
        uid: '',
        userId: ''
    }


    componentDidMount() {
        AsyncStorage.multiGet(
            ['client', 'expiry',
            'access_token', 'uid',
            'account_balance', 'userId'
            ]
        )
        .then((result) => {
            this.setState({
                client: result[0][1],
                expiry: result[1][1],
                accessToken: result[2][1],
                uid: result[3][1],
                userId: result[5][1]
            });
        })
        .then(() => {
            this.getPreviousMessages();
        })
        .then(() => {
            this.createSocket();
        })
        .catch(() => {
            //error logic
        });
    }

    getPreviousMessages() {
        //when we open the chat page we should load previous messages
        const { chatId } = this.props.navigation.state.params;
        const { client, accessToken, uid, userId } = this.state;
        const url = yourRootUrl + '/chats/' + chatId;
        const headers = {
            'access-token': accessToken,
            client,
            expiry,
            uid
        };
        axios.get(url, { headers })
        .then((response) => {
            /*
                lets construct our messages to be in
                same format as expected by GiftedChat
            */
            const allMessages = [];
            response.data.included.forEach((x) => {
                if (x.attributes.system) {
                    const sysMessage = {
                        _id: x.id,
                        text: x.attributes['message-text'],
                        createdAt: new Date(x.attributes['created-at']),
                        system: true
                    };
                    allMessages.push(sysMessage);
                } else {
                    const userMessage = {
                        _id: x.id,
                        text: x.attributes['message-text'],
                        createdAt: new Date(x.attributes['created-at']),
                        user: {
                            _id: x.attributes['sender-id'],
                            avatar: x.attributes['sender-avatar'],
                        },
                        image: x.attributes.image,
                    };
                    allMessages.push(userMessage);
                }
            });
            if (allMessages.length === response.data.included.length) {
                //lets sort messages according to date created
                const sortAllMessages = allMessages.sort((a, b) =>
                        b.createdAt - a.createdAt
                    );
                this.setState((previousState) => {
                    return {
                        messages: GiftedChat.append(previousState.messages, sortAllMessages)
                    };
                });
            }
        })
    }

    createSocket() {
        //assuming you have set up your chatchannel in your rails backend
        const { client, accessToken, uid, userId } = this.state;
        const { chatId } = this.props.navigation.state.params; //using react-navigation
        const WEBSOCKET_HOST = websocketUrl +
            'access-token=' + accessToken + '&client=' +
            client + '&uid=' + uid;

        const cable = ActionCable.createConsumer(WEBSOCKET_HOST);
        this.channel = cable.subscriptions.create(
            {
                channel: 'ChatChannel',
                id: chatId
            }, {
                received: (data) => {
                    console.log('Received Data:', data);

                    if ((data.message.sender_id !== parseInt(userId))
                        || (data.message.image !== null)) {
                        //ensuring you do not pick up your own messages

                        if (data.message.system === true) {
                            const sysMessage = {
                                _id: data.message.id,
                                text: data.message.message_text,
                                createdAt: new Date(data.message.created_at),
                                system: true
                            };
                            this.setState((previousState) => {
                                return {
                                    messages: GiftedChat.append(previousState.messages, sysMessage)
                                };
                            });
                        } else {
                            const userMessage = {
                                _id: data.message.id,
                                text: data.message.message_text,
                                createdAt: new Date(data.message.created_at),
                                user: {
                                    _id: data.message.sender_id,
                                    avatar: data.message.sender_avatar,
                                },
                                image: data.message.image,
                            };
                            this.setState((previousState) => {
                                return {
                                    messages: GiftedChat.append(previousState.messages, userMessage)
                                };
                            });
                        }
                    }
                },

                connected: () => {
                    console.log(`Connected ${chatId}`);
                },

                disconnected: () => {
                    console.warn(`${chatId} was disconnected.`);
                },

                rejected: () => {
                    console.warn('connection rejected');
                },
        });
    }

    onSend(messages = []) {
        const { chatId } = this.props.navigation.state.params;
        const { client, accessToken, uid, userId } = this.state;
        this.setState((previousState) => {
            return {
                messages: GiftedChat.append(previousState.messages, messages)
            };
        });
        messages.forEach((x) => {
            const url = yourRootUrl + '/messages';
            const headers = {
                'access-token': accessToken,
                client,
                expiry,
                uid
            };
            const data = {
                chat_id: chatId,
                sender_id: userId,
                sender_name: name,
                message_text: x.text,
                image: x.image
            };
            /*
                send the message to your rails app backend
                hopefully you have a callback in your model like
                after_create :broadcast_message
                then broadcast to the chat channel from your rails backend
            */
            axios.post(url, data, { headers })
            .then(response => console.log(response));
        });
    }

    renderBubble(props) {
        return (
            <Bubble
                {...props}
                wrapperStyle={{
                    left: {
                        backgroundColor: '#f9f9f9',
                    }
                }}
            />
        );
    }

    renderSystemMessage(props) {
        return (
            <SystemMessage
                {...props}
                containerStyle={{
                  marginBottom: 15,
                }}
                textStyle={{
                  fontSize: 14,
                  textAlign: 'center'
                }}
            />
        );
    }

    render() {
        return (
            <GiftedChat
                messages={this.state.messages}
                onSend={message => this.onSend(message)}
                user={{
                    _id: parseInt(userId)
                }}
                renderBubble={this.renderBubble}
                renderSystemMessage={this.renderSystemMessage}
            />
        );
    }
}
Related