Trying to update a textarea with string from an OpenAI request

Can anyone assist me with an issue I’m facing. I’m trying to append a string received back from an OpenAI request to an exisitng textarea element. The requested string is received and stored in the back end in an array called response.data.choices[0].text. I’m currently trying to append the {response} string into an existing textarea in the front end using the code <textarea id="textarea">{response}</textarea>. The issue seems to be that code: <textarea id="textarea">{response}</textarea> is creating the textarea on screen (on launch) prior to string data being received/stored into the response array as there is significant latency with respect to the response time between the back end request and what is received from OpenAI. I’m unsure how to overcome this issue do i need to have some sort of thread to constantly check for changes in the array than delete and recreate the textarea element? I honestly have no clue how to bypass this issue any help would be so greatly appreciated. Thanks again for your time.

It’s really important that the textarea is to appear before the response is received.

APP.JS (Front End)

import React, { useState } from 'react';


function App() {
  const [message, setMessage] = useState('');
  const [response, setResponse] = useState('');

  const handleSubmit = (e) => {
      e.preventDefault();
      fetch('http://localhost:3001/', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
      },
      body: JSON.stringify({ message }),
    })

      .then((res) => res.json())
      .then((data) => setResponse(data.message));
  };

  return (
    <body>
      <div className="App">
        <form onSubmit={handleSubmit}> 
        <div class="section"></div>

            //User inputs there question to OpenAI
            <input type="text" class="topic" placeholder="Interest Rates, Quantum Mechanics, Team Management"
              value={message}
              onChange={(e) => setMessage(e.target.value)}
            ></input>

            //Submits user input to back end
            <div> <button id="generate" type="submit">Generate</button> </div>
            
            //Attempting to write the response from back end to textarea (cannot due to latency)
            <textarea id="textarea">{response}</textarea>

            <div class="break">
            </div>
            
        </form>
        //prints back end response from OpenAI (for refference only)
        <h4>{response}</h4>
      </div>
    </body>
    
  );
}

export default App

INDEX.JS (Back End)

const OpenAI = require('openai');
const { Configuration, OpenAIApi } = OpenAI;

const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
const port = 3001;

const configuration = new Configuration({
    organization: "org-kEBxx4hVwFZZeA",
    apiKey: "sk-jmYuTSCZvxCjidnbTpjFT3BlbkFJ9nFcGxbH4V",
});
const openai = new OpenAIApi(configuration);
 
app.use(bodyParser.json());
app.use(cors());

app.post('/', async (req, res) => {
    const { message } = req.body;
    const response = await openai.createCompletion({
        model: "text-davinci-003",
        prompt: `${message}`,
        max_tokens: 100,
        temperature: 0,
      });
    console.log(response.data)
    if(response.data.choices[0].text){
        res.json({message: response.data.choices[0].text})
    }
    
});

app.listen(port, () => {
    console.log("Listening...")
});

>Solution :

I would check out this link for more information on textareas. The short of it is you should replace

<textarea id="textarea">{response}</textarea>

with

<textarea id="textarea" value={response} />

Although, if the user is not going to be editing the response from OpenAI, I would consider just using a styled text element like <p> or <h4> like you have below. Textarea’s big benefit is allowing use to edit multiline inputs, which perhaps doesn’t seem necessary for it’s use here.

As a second note, it sounds like you don’t want the textarea to appear until the response is received. For that, you can do something like

{response.length > 0 && <textarea id="textarea" value={response} />}

which will refrain from displaying the element until the response is not empty. You might also choose to instead track the status of the backend using a boolean for readability.

Leave a Reply