Posts.map не является функцией React Spring Boot WebSocket

в общем у меня проблема. Я хочу отправить сообщение в конечную точку, в которой нужно отправить все сообщения из базы данных в тему веб-сокета, чтобы клиент мог их все получить. Вот мой метод отправки сообщения (я использую MONGODB):

@PostMapping("/send")
    public void sendMessage(@RequestBody Message message){
        mongoTemplate.insert(message);

    simpMessagingTemplate.convertAndSend("/topic/greetings", mongoTemplate.query(Message.class).as(Message.class).all());
    }

В общем ничего из ряда вон выходящего, с этим проблем нет, все в тему, все круто. Теперь все это нужно отловить на клиенте, для этого я написал следующий код:

var stompClient: any = null;
const SockJS = require('sockjs-client')
const Stomp = require('stompjs')
function App() {
  const [posts, setPosts]: any = useState("")
  const [handleInput, setHandleInput] = useState("")


  function setValueInput(e: any){
    setHandleInput(e.target.value);
  }
  function sendMessage(e: any){
    e.preventDefault();
    axios.post('http://localhost:8080/api/send', {
      id: Date.now(),
      text: handleInput,
    })
        .then(function (response) {
          setHandleInput("");
        })
        .catch(function (error) {
          console.info(error);
        });
  }
  useEffect(function (){
      let Sock = new SockJS('http://localhost:8080/ws')

      stompClient= Stomp.over(Sock)

      stompClient.debug = null

      setTimeout(function() {
          stompClient.connect({},function (frame: any){


              console.info(`Connected: ${frame}`)


              stompClient.subscribe("/topic/greetings", function (greeting: any) {
                  console.info(greeting.body)
                  const tempParsedJson = JSON.stringify(greeting.body)
                  console.info(tempParsedJson)
                  setPosts(tempParsedJson)
              });

          }, 1200)})
  }, [])

  return (
    <div className = "App">
        {posts && posts.map((data: any) => (
    <Form key = {data.id} {...data}/>
            ))}
      <div className = {style.dop}>
        <input onChange = {setValueInput} value = {handleInput} className = {style.input}/>
        <a onClick = {sendMessage} className = {style.button}>Submit</a>
      </div>
    </div>
  );
}

export default App;

Короче, успешно подписываемся на тему, опять все хорошо, но пока мне не нужно получить объекты. В консоли вижу это:

Первое — это то, что я получаю от Java, второе — это то, что я пытаюсь перевести в JSON. После отправки сообщений, по моему коду, мы видим, что я пытаюсь отобразить эти данные отдельно в каждом элементе, но при попытке получаю ошибку:

ОШИБКА posts.map не является функцией

Я надеюсь, что вы можете помочь, я не знаю, что делать. Кстати пробовал через gson перевести List на Java в json, но выводится та же ошибка.. Помоги пожалуйста.. Моя форма:

const Form: React.FC<Props> = ({id, text}) => {
    function handleDelete(e: any) {
        e.preventDefault();
        axios.post('http://localhost:8080/api/deleteMessage', {
            id: id,
            text: text,
        })
            .then(function (response) {
            })
            .catch(function (error) {
                console.info(error);
            });
    }
    return (
        <div>
            <div className = {style.wrapper}>
                <div className = {style.coontainer}>
                    <div className = {style.form}>
                        <p>{text}</p>
                        <a onClick = {handleDelete} style = {{display: "inline", margin: "0 20px", color: "white", cursor: "pointer"}}>Удалить</a>
                    </div>
                </div>
            </div>
        </div>
    );
};

export default Form;
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
50
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Поскольку ваш код является асинхронным и не извлекается немедленно, и может потребоваться время, пока данные не будут получены, ваши данные не будут определены, а сообщения будут пустой строкой до тех пор, пока данные не будут извлечены, тогда он будет обновлен для замены данными

поэтому эта ошибка была выброшена на вашу консоль, потому что экземпляр String не имеет метода с именем «карта».

поэтому, чтобы решить эту проблему, у вас есть решения.

во-первых, добавить тернарный оператор (?) после слова posts, чтобы быть похожим на эти сообщения?.map() это заставит код работать, только если данные существуют и у них есть метод карты (другими словами, если данные представляют собой массив)

или второе решение определяет значение начального состояния как пустой массив

Если posts — правдивая строка, posts?.map(...) выбросит posts?.map is not a function.

Luke Woodward 04.04.2023 23:53

нет, не будет! потому что это все равно, что сказать js, хорошо, если у меня есть сообщения, и эти сообщения содержат карту, тогда сделайте это... но это не так, игнорируйте это и не выдавайте ошибку

Youssef_Ayman168 05.04.2023 00:10

Э-э, да, это выдаст эту ошибку, потому что я проверил ее в консоли браузера, и она действительно выдала эту ошибку. Попробуйте сами, если не верите мне. posts?.map(...) проверяет, является ли posts ложным, прежде чем пытаться вызвать .map его, он не проверяет, является ли posts.map неопределенным (и, следовательно, ложным). Возможно, вы имели в виду что-то вроде posts && posts.map && posts.map(...), что делает эту проверку?

Luke Woodward 05.04.2023 23:31

да, а также, чтобы избежать этого длинного оператора, сделайте начальное состояние пустым массивом.

Youssef_Ayman168 06.04.2023 00:22

Сначала сделайте начальное состояние пустым массивом, как этот фрагмент кода:

const [posts, setPosts]: any = useState([]);

А затем используйте тернарный оператор при использовании функции карты, например:

posts && posts?.map(() => {})

Если posts — правдивая строка, posts?.map(...) выбросит posts?.map is not a function.

Luke Woodward 04.04.2023 23:55
Ответ принят как подходящий

Другие ответы указывали на тот факт, что вам нужно инициализировать posts как массив, когда вы объявляете его с помощью хука useState в следующей строке:

  const [posts, setPosts]: any = useState([])       // [], not ""

но они, похоже, упустили проблему в этом фрагменте кода:

                  console.info(greeting.body)
                  const tempParsedJson = JSON.stringify(greeting.body)
                  console.info(tempParsedJson)
                  setPosts(tempParsedJson)

greeting.body выглядело хорошо для меня: судя по вашему первому console.info выводу, это выглядело как массив, содержащий некоторые объекты, и вы, безусловно, .map могли бы это исправить, если бы это было так. Однако при дальнейшем рассмотрении, если бы это действительно были проанализированные данные JSON, ваш браузер отобразил бы это по-другому. В частности, вы сможете расширять части данных JSON.

Однако в строке ниже вы не помогаете себе.

Вы берете данные, которые у вас есть в greeting.body, а затем преобразуете их в строки. Затем вы называете свою переменную, чтобы создать впечатление, что вы «разобрали» JSON, что бесполезно. Вы не разобрали JSON здесь, на самом деле вы сделали наоборот. Синтаксический анализ — это процесс преобразования строки JSON в объекты и массивы JavaScript, преобразование строк — это другой способ.

Следовательно, исправление состоит не в том, чтобы вызывать JSON.stringify на greeting.body, а вместо этого вызывать JSON.parse на нем.

Ваш сервер Java мог отправить JSON по сети на ваш интерфейс. Я ожидаю, что Axios проанализирует этот JSON в объекты JavaScript для вас, чтобы вы могли сразу начать их использовать, но по причинам, в которых я не уверен, это не так.

Обратите внимание, что у меня нет вашего бэкенда и я не запускал этот код, так что могут быть другие проблемы. Я только объясняю, как исправить ошибку «posts.map не является функцией».

Я решил свою проблему так же, как вы сказали, я разобрал строку, которую я получаю с сервера, в объекты js, используя: JSON.parse(greeting.body), спасибо!

panic08 05.04.2023 21:15

@panic08: рад, что ты смог решить свою проблему. Извиняюсь, если язык моего ответа был, возможно, слишком критическим; Я переработал его и немного смягчил. Кажется, я ошибался, полагая, что Axios возвращает вам проанализированные объекты JS. Я ожидал, что он сделает это для вас, я не уверен, почему этого не произошло.

Luke Woodward 06.04.2023 00:02

Другие вопросы по теме

Вспомогательная функция с Redux Dispatch/React Hooks
UseState по-прежнему имеет старое значение при переходе на предыдущую страницу
React Swiper с большим пальцем неправильно пересчитывает количество слайдов (добавляет слайды вместо замены)
Как повторно использовать следующий фрагмент кода?
Я получаю Невозможно прочитать свойства неопределенного (чтение «квартира»), пока поле существует и тип данных соответствует
Сортировка MUI DataGrid — можно ли учитывать несколько столбцов при определении модели сортировки по умолчанию?
Как предотвратить перезагрузку текущей страницы и перейти на домашнюю страницу в React?
Лучше использовать useState или useRef с множественной формой ввода?
Как исправить неверную конфигурацию схемы в Mongoose и React?
Непосредственное изменение глобальной переменной в компоненте React приводит к неожиданным результатам рендеринга