Marc Gault
Marc Gault

Reputation: 73

TypeError: Cannot destructure property 'text' of 'props.message' as it is undefined

I'm getting a TypeError in my ChatMessage function.

I have tried a few different solutions, none pertaining to this exact scenario. This is a Firebase Chat Application, obviously not unique, but I'm attempting to integrate TypeScript into this, still learning and hoping to find a solution I can learn more from.

App.tsx - this is the core of the code

import './App.css';

import firebase from 'firebase/app';
import 'firebase/firestore';
import 'firebase/auth';

import { useAuthState } from 'react-firebase-hooks/auth';
import { useCollectionData } from 'react-firebase-hooks/firestore';

firebase.initializeApp ({
    //Removed on stackoverflow for security reasons
})

const auth = firebase.auth();
const firestore = firebase.firestore();

function App() {
  const [user] = useAuthState(auth);

  return (
    <div className="App">
      <header>
        <h1>⚛️🔥💬</h1>
        <SignOut />
      </header>

      <section>
        {user ? <ChatRoom /> : <SignIn />}
      </section>
    </div>
  );
}

function SignIn() {
  const signInWithGoogle = () => {
    const provider = new firebase.auth.GoogleAuthProvider();
    auth.signInWithPopup(provider);
  }

  return (
    <>
    <button onClick={signInWithGoogle}>Sign in with Google</button>
    <p>Do not violate the community guidelines or you will be banned for life!</p>
    </>
  )
}

function SignOut() {
  return auth.currentUser && (
    <button className="sign-out" onClick={() => auth.signOut()}></button>
  )
}

function ChatRoom() {
  const dummy = useRef<HTMLDivElement>(null);

  const messagesRef = firestore.collection('messages');
  const query = messagesRef.orderBy('createdAt').limit(25);

  const [messages] = useCollectionData(query, {idField: 'id'});

  const [formValue, setFormValue] = useState('');

  const sendMessage = async(e : any) => {
    e.preventDefault();

    const user = auth.currentUser;

    if (user) {
      const { uid, photoURL } = user;

      await messagesRef.add ({
        text: formValue,
        createdAt: firebase.firestore.FieldValue.serverTimestamp(),
        uid,
        photoURL
      });

      setFormValue('');
      dummy.current!.scrollIntoView({ behavior: 'smooth' });
      
    } else {
      //Handle Errors
    }
  };

  return (
    <>
      <main>
        {messages && messages.map((msg: any) => <ChatMessage key={msg.id} messsage={msg}/>)}

        <span ref={dummy}></span>
      </main>

      <form onSubmit={sendMessage}>
        <input value={formValue} onChange={(e) => setFormValue(e.target.value)} placeholder="Send Message..."/>
        <button type="submit" disabled={!formValue}>🕊️</button>
      </form>
    </>
  )
}

function ChatMessage(props: any) {
  const { text, uid, photoURL } = props.message;

  const messageClass = uid === auth.currentUser?.uid ? 'sent' : 'received';

  return (
    <>
    <div className={`message ${messageClass}`}>
      <img src={photoURL || 'https://api.hello-avatar.com/adorables/myseed'} />
      <p>{text}</p>
    </div>
    </>
  )
}

export default App;

ChatMessage Function - the function where the error is occurring (TypeScript is not catching this issue, it only occurs after build)

function ChatMessage(props: any) {
  const { text, uid, photoURL } = props.message;

  const messageClass = uid === auth.currentUser?.uid ? 'sent' : 'received';

  return (
    <>
    <div className={`message ${messageClass}`}>
      <img src={photoURL || 'https://api.hello-avatar.com/adorables/myseed'} />
      <p>{text}</p>
    </div>
    </>
  )
}

Error - the specific error in the ChatMessage function

TypeError: Cannot destructure property 'text' of 'props.message' as it is undefined.

Edit 1 - I believe the error explains that the property "text" of "props.message" is not defined, although its type is "any". Would I need to define that again to a specific type?

Edit 2: Solution - There was a typo in my script. Message was spelt "Messsage". Thanks for your help everyone!

Upvotes: 2

Views: 6078

Answers (2)

Rush W.
Rush W.

Reputation: 1361

The problem is because of a typo. <ChatMessage key={msg.id} messsage={msg}/>

It's messsage instead of message. So when you try to destructure, it won't find the property message in props.

Upvotes: 0

Sinan Yaman
Sinan Yaman

Reputation: 5937

The problem here is when you use destructuring like

const {foo} = bar

you are expected a bar object such that it consists of a foo field:

   const bar = {
     foo: ''
  }

In your case, your props.messages object doesn't seem to contain a text field, that is why you are getting the error

Upvotes: 1

Related Questions