0

I'm learning React and is doing a personal project where i'm creating a chatbot with api.ai agent. I'm using api.ai npm package in my project where the user can ask a question and my agent will reply to the answer based on the question.I'm getting the response correctly from the agent, but the response is not rendered in the page until there is keypress event.

Below is my code

    import React, {
Component
} from 'react';
import ChatMessageComposer from 
'../ChatMessageComposer/ChatMessageComposer';
 import ChatHistory from '../ChatSection/ChatHistory/ChatHistory';
 import apiai from 'apiai-promise';
class Chat extends Component {
state = {
    messages: [], //[{from: 'bot', message: 'Hi'}]
    inputValue: ''
}
atKeyPress = (event) => {
    if (event.key !== 'Enter') {
        return;
    }
    this.setState((prevState) => {
        prevState.messages.push({
            message: this.state.inputValue,
            from: 'you'
        })
    })

    let data = this.state.inputValue;
    var app = apiai("");

    app.textRequest(data, {
        sessionId: ''
    }).then((response) => {
        console.log(response);
        this.setState((prevState) => {
            prevState.messages.push({
                message: response.result.fulfillment.speech,
                from: 'bot'
            })
        })
    }).catch((error) => {
        console.log(error);
    })


    this.setState({
        inputValue: ''
    });

}
render() {
    console.log("here ", this.state.messages)
    return (<
        div >
        <
        ChatHistory messages={
                this.state.messages
            } > < /ChatHistory> <
        ChatMessageComposer 
                changed={
                    (event) => this.setState({
                        inputValue: event.target.value
                    })
                }
                atKeyPress={
                    (event) => this.atKeyPress(event)
                }
                value={
                    this.state.inputValue
                }

            >
                < /ChatMessageComposer> <
        /div>

    )
}

}

    export default Chat;

This is chatmessagecomposer component,

    export default Chat;
    const chatMessageComposer = (props) => {
    return (
    <div className={classes.Chatinput}>
    <input placeholder="Talk to me..." className={classes.Userinput}                 type="text" value={props.value} onChange={props.changed} onKeyPress=        {props.atKeyPress}/>
    </div>
    )
    }
   const chatHistory = (props) => (
   <div className={classes.ChatOutput}>
   {props.messages.map((message, i)=>(
   <ChatMessage key={i} message={message} />
  ))}
  </div

Any help will be appreciated

Annette
  • 214
  • 1
  • 3
  • 16

1 Answers1

2

You are not returning the mutated state in your setState method call. Try doing this

this.setState((prevState) => {
        prevState.messages.push({
            message: response.result.fulfillment.speech,
            from: 'bot'
        })
        return prevState; 
    })
Hunaid Hassan
  • 732
  • 5
  • 13
  • 1
    you shouldn't be mutating state, either. copy/create a new state obj. – Tyler Sebastian Feb 23 '18 at 20:15
  • 1
    You are right. He shouldn't be saving the state in the component at all maybe. You know, use redux? But I am trying to suggest the minimum he can do to make his code work. He said he's a rookie after all – Hunaid Hassan Feb 23 '18 at 20:17
  • thanks @hunaidHassan, it works :. i will try with redux once im comfortable with it – Annette Feb 23 '18 at 20:27