Reputation: 566
I am making a blog using React and MongoDB. I retrieve the data from MongoDB, here is my component:
import React, { Component } from 'react';
import axios from 'axios';
export default class Post extends Component {
constructor(props) {
super(props);
this.state = {
posts: []
};
}
truncateText = text => {
return text.substring(0, 500) + "...";
}
allPosts = () => {
return this.state.posts.map(function(astroPost, i){
return <div class="post-container">
<img className="post-info-container__image" src={astroPost.picture} alt=""/>
<div className="post" posts={astroPost} key={i}>
<div class="post-container__text">
<h2>{astroPost.title}</h2>
<p className="date">{astroPost.date}</p>
<p className="post-info-container__text">{this.truncateText(astroPost.postContent)}</p>
<button>Read more</button>
</div>
</div>
</div>
})
}
componentDidMount() {
axios.get('http://localhost:4000/')
.then(response => {
this.setState({posts: response.data})
console.log(response)
})
.catch(function(error) {
console.log(error)
})
}
render() {
return (
<div>
{ this.allPosts() }
</div>
)
}
}
I want to truncate the text of my post so that a post shows only 500 symbols. I achieved this by doing so:
return this.state.posts.map(function(astroPost, i){
return <div class="post-container">
<img className="post-info-container__image" src={astroPost.picture} alt=""/>
<div className="post" posts={astroPost} key={i}>
<div class="post-container__text">
<h2>{astroPost.title}</h2>
<p className="date">{astroPost.date}</p>
<p className="post-info-container__text">{astroPost.postContent.substring(0, 500) + "..."}</p>
<button>Read more</button>
</div>
</div>
</div>
But I want to do it with a function that get's called on the text, so I kept the same logic in a function called truncateText, but when I call it like this:
return this.state.posts.map(function(astroPost, i){
return <div class="post-container">
<img className="post-info-container__image" src={astroPost.picture} alt=""/>
<div className="post" posts={astroPost} key={i}>
<div class="post-container__text">
<h2>{astroPost.title}</h2>
<p className="date">{astroPost.date}</p>
<p className="post-info-container__text">{astroPost.postContent.truncateText()}</p>
<button>Read more</button>
</div>
</div>
</div>
})
}
It says that TypeError: astroPost.postContent.truncateText is not a function
How can I call that function and perform the truncation properly?
Upvotes: 0
Views: 49
Reputation: 41
You have not bound truncatetext
to the component: that causes problems with the context. In the constructor, you can use this.truncatetext = this.truncatetext.bind(this)
:
constructor(props) {
super(props);
this.state = {
posts: []
};
this.truncateText = this.truncateText.bind(this);
}
Upvotes: 1
Reputation: 1182
astroPost is just the element inside the array you are iterating.
Also, if you create a function in your class, you have to do one of this things: or bind the function to the "this" element, or create the function as an arrow function. I recommend second option. So, for your case, you would end with something like this:
truncateText = text => {
return text.substring(0, 500) + "...";
}
and then, inside your map you can call it like this:
<p className="post-info-container__text">{this.truncateText(astroPost.postContent)}</p>
Upvotes: 0