Reputation: 73
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
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
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