0

I'm trying to fetch data from graphQL, and I know that by putting function into the react UseEffect(), I would be able to call the function once the data is updated and constructed. However, I'm working on a chatroom, and the data does not appear on the screen:

import {
  CREATE_MESSAGE_MUTATION,
  MESSAGES_QUERY,
  MESSAGE_SUBSCRIPTION,
} from "../graphql";
import { useQuery, useSubscription } from "@apollo/client";
import React, { useEffect } from "react";
import { Tag } from "antd";
const ChatBox = ({ me, friend, ...props }) => {
  //me friend are strings

  const chatBoxName = [me, friend].sort().join("_");
  const { loading, error, data, subscribeToMore } = useQuery(MESSAGES_QUERY, {
    variables: { name: chatBoxName },
  });

  useEffect(() => {
    try {
      subscribeToMore({
        document: MESSAGE_SUBSCRIPTION,
        variables: { name: chatBoxName },
        updateQuery: (prev, { subscriptionData }) => {
          if (!subscriptionData.data) return prev;
          const newMessage = subscriptionData.data;
          console.log("Subscribing more data: ", newMessage);
        },
      });
    } catch (e) {
      console.log("Error in subscription:", e);
    }
  }, [subscribeToMore]);

  if (loading) return <p>loading ...</p>;
  if (error) return <p>Error in frontend chatbox: {error}</p>;

  return (
    <div className="App-messages">
      {console.log(data.chatboxs[0].messages)}
      {data.chatboxs[0].messages.map(({ sender: { name }, body }) => {
        <p className="App-message">
          <Tag color="blue">{name}</Tag>
          {body}
        </p>;
      })}
    </div>
  );
};

export default ChatBox;

After a small delay of loading ..., it turns to the <div className="App-messages"> with no messages inside. However, on the console I can clearly see the messages that I want to print. What is the problem of the function in UseEffect()? I would be so appreciated if anyone can help .

1
  • It looks like you're missing chatBoxName in the useEffect dependency array. That would be where I start Commented Dec 25, 2021 at 14:50

1 Answer 1

1
{data.chatboxs[0].messages.map(({ sender: { name }, body }) => { // <- this part
    <p className="App-message">
      <Tag color="blue">{name}</Tag>
      {body}
    </p>;
  })}

As a callback, you declared a function that does not return JSX elements.

Replace with this

{data.chatboxs[0].messages.map(({ sender: { name }, body }) => (
    <p className="App-message">
      <Tag color="blue">{name}</Tag>
      {body}
    </p>;
  ))}
Sign up to request clarification or add additional context in comments.

2 Comments

Oh god thank you that works for me! Is it because in {} this should be javascript instead of JSX?
Yes, my friend, this is how javascript's map function works, it loops through elements and reassigns each value to what you have returned inside the callback function. So if nothing is returned, then each value is going to be undefined after the loop and no HTML is going to be rendered.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.