At this moment I'm trying to build a frontend page with a combination of React and TypeScript. What I'm trying to do is to fetch the "words" via a get method of axios and assign the data to an array, and then display it on the frontend page, which is fairly simple. I've already made sure that the backend part works fine using Postman.
As I didn't find a good "React & TypeScript" tutorial that exactly matches what I want to do, I'm studying with a "React & JavaScript" tutorial. What I find a little odd is that the completely valid part written in "React & JavaScript" causes an error "TypeError: this.state.wordsData.map is not a function" in my case, which is written in "React & TypeScript".
Here is my code.
import React from 'react';
import axios from 'axios'
import Word from '../interfaces/Word.interface';
class Home extends React.Component{
state = {
wordsData:new Array<Word>()
}
componentWillMount(){
axios.get('http://localhost:8080/pictionarizerservices/api/words')
.then(res => {
const data = res.data;
console.log("The content of res: ");
console.log(res);
this.setState({
wordsData:{
id: data.id,
ownLangWordName: data.ownLangWordName,
targetLangWordName: data.targetLangWordName,
ownLangExSentence: data.ownLangExSentence,
targetLangExSentence: data.targetLangExSentence,
createdDate: data.createdDate
}
})
})
}
render(){
return(
<div>
<h2>Words:</h2>
<table>
<thead>
<tr>
<th>ID</th>
<th>Word (OL)</th>
<th>Word (TL)</th>
<th>Sentence (OL)</th>
<th>Sentence (TL)</th>
<th>Created Date</th>
</tr>
</thead>
<tbody>
{this.state.wordsData.map(singleWord=>
<RowCreator
id={singleWord.id}
ownLangWordName={singleWord.ownLangWordName}
targetLangWordName={singleWord.targetLangWordName}
ownLangExSentence={singleWord.ownLangExSentence}
targetLangExSentence={singleWord.targetLangExSentence}
createdDate={singleWord.createdDate}
/>)}
</tbody>
</table>
</div>
)
}
}
class RowCreator extends React.Component<Word>{
render(){
let word = this.props;
return(
<tr>
<td>{word.id}</td>
<td>{word.ownLangWordName}</td>
<td>{word.targetLangWordName}</td>
<td>{word.ownLangExSentence}</td>
<td>{word.targetLangExSentence}</td>
<td>{word.createdDate}</td>
</tr>
)
}
}
export default Home;
I modified the syntax a little bit in order to adjust to TypeScript, but the followings are all I changed.
from
state = {
patientData:[]
}
to
state = {
wordsData:new Array<Word>()
}
,and from
class RowCreator extends React.Component{
...
to
class RowCreator extends React.Component<Word>{
...
That's all.
What I already know by studying by myself about TypeScript is that TypeScript is a strict superset of JavaScript, and all valid code written in JavaScript should be valid in TypeScript as well. Also, especially when writing in Visual Studio Code, TypeScript's error detecting feature is excellent and you'll find a lot more errors beforehand compared to when you are writing in JavaScript. I made sure that all the error markups were gone before running the program, and now I get this "TypeError: this.state.wordsData.map is not a function" error as a run time error.
How can I get the part
<tbody>
{this.state.wordsData.map(singleWord=>
<RowCreator
id={singleWord.id}
ownLangWordName={singleWord.ownLangWordName}
targetLangWordName={singleWord.targetLangWordName}
ownLangExSentence={singleWord.ownLangExSentence}
targetLangExSentence={singleWord.targetLangExSentence}
createdDate={singleWord.createdDate}
/>)}
</tbody>
to work in TypeScript?
setStateincomponentWillMountof theHomecomponent assings an object tothis.state.wordsData. Perhaps you meant to assign an array or push into the existing array.