Update messages from api every second

Viewed 1104

I am using react-native gifted-chat for my chat interface in my react native mobile application, in my component will mount I get the messages for the user from an api and render it in the Gifted chat interface, any message sent in gifted chat is also sent to an api, which saves the message in the db. Now I want to update the messages state every second so that when the other user also sends a message the current user it updates, I have tried using set interval but the emulator always hangs, please what will be the most efficient way to update the messages array other than what I have done

 constructor(props) {
    super(props);
    this.state = {
        messages: []
    };
    this.checker = this.checker.bind(this);
};
checker(){
    const {params} = this.props.navigation.state;
           this.setState({loading: true});
           var bodyParameters = {
               id: params.id,
               receiver_id: params.receiver_id
           }
          /*    var config = {
               headers: {'Authorization': "Bearer " + this.state.token}
          };*/
          axios.post(
              'http://10.0.2.2:8000/api/messages',
              bodyParameters,
          //      config
          ).then((response) => {
           this.setState({loading: false});
           console.log(response);   
           var len = response.data.success?response.data.success.length:null;
           for (let i = 0; i < len; i++) {
               let row = response.data.success[i];
               console.log(row.id, row.user1.id);console.log("chat")
               this.setState(prevState => ({
                   messages: [...prevState.messages, {_id: row.id, text: row.message, 
                       createdAt: row.created_at, user: {_id: row.user1.id,name: row.user1.first_name+' '+row.user1.last_name}}],
               }), console.log(this.state.messages));
               console.log("checker");
           };
          }).catch((error) => {
           this.setState({loading: false}); 
                   console.log(error); 
                  });      
}
componentDidMount(){
this.interval = setInterval(() => this.checker(), 1000);
}
componentWillUnmount() {
        clearInterval(this.interval);
      }
componentWillMount() {
    const {params} = this.props.navigation.state;
 /*   var pusher = new Pusher('1363556f717d953dcf86', {
        cluster: 'mt1',
        forceTLS: true
      });
      var channel = pusher.subscribe('private-messages.'+ params.id);
      channel.bind('MessageSent', function(data) {
        console.log(data);
      });*/
        this.setState({loading: true});
        var bodyParameters = {
            id: params.id,
            receiver_id: params.receiver_id
        }
    /*    var config = {
            headers: {'Authorization': "Bearer " + this.state.token}
       };*/
       axios.post(
           'http://10.0.2.2:8000/api/messages',
           bodyParameters,
     //      config
       ).then((response) => {
        this.setState({loading: false});
        console.log(response);   
        var len = response.data.success?response.data.success.length:null;
        for (let i = 0; i < len; i++) {
            let row = response.data.success[i];
            console.log(row.id, row.user1.id);console.log("chat")
            this.setState(prevState => ({
                messages: [...prevState.messages, {_id: row.id, text: row.message, 
                    createdAt: row.created_at, user: {_id: row.user1.id,name: row.user1.first_name+' '+row.user1.last_name}}],
            }), console.log(this.state.messages));
            console.log("contjii");
        };
       }).catch((error) => {
        this.setState({loading: false});
            Alert.alert(
                'Error',
                 'Internal Server Error, please try again later',
                [
                  {text: 'OK'},
                ],  );    
                console.log(error); 
               });    
 /*   this.setState({
      messages: [
        {
          _id: 1,
          text: 'Hello developer',
          createdAt: new Date(),
          user: {
            _id: 1,
            name: 'React Native',
            avatar: 'https://placeimg.com/140/140/any',
          },
      //    image: 'https://facebook.github.io/react/img/logo_og.png',
          // additional custom parameters
          sent : true,
          received : true,
        },
      ],
    })*/
  }

  onSend(messages = []) {
      console.log(messages);
      const {params} = this.props.navigation.state;
      messages[0].sent = true;
    var bodyParameters = {
        id: params.id,
        receiver_id: params.receiver_id,
        message: messages[0].text
    }
/*    var config = {
        headers: {'Authorization': "Bearer " + this.state.token}
   };*/
   axios.post(
       'http://10.0.2.2:8000/api/sendMessage',
       bodyParameters,
 //      config
   ).then((response) => {
    this.setState({loading: false});
    console.log(response);   

   }).catch((error) => {
    this.setState({loading: false});
        Alert.alert(
            'Error',
             'Internal Server Error, please try again later',
            [
              {text: 'OK'},
            ],  );    
            console.log(error); 
           }); 
      this.setState(previousState => ({
      messages: GiftedChat.append(previousState.messages, messages),
    }));  
  }
render() {
    const {params} = this.props.navigation.state;
    return (
<GiftedChat
        messages={this.state.messages}
       //  inverted={false}
        onSend={messages => this.onSend(messages)}
        user={{
          _id: params.id,
        }}
      />
 );
 }
2 Answers

The most efficient way to handle this is to use a Web Sockets protocol which would send a notification from the server to the UI Client. It's hard to give you an example because we don't know your server stack, but something like SignalR in.Net world would be perfect here.

The premise here is that instead of asking the server every second for new messages, the server will instead notify the client when new messages are available. You'd be saving a lot of resources that way.

The problem with the code is that the setInterval keeps on sending API calls relentlessly without caring the previous call has returned or not. This has queued up a lot of requests at once on the server. To solve this problem, You should wait for the API response before making the next API call.

Related