Mahma Deva
Mahma Deva

Reputation: 566

React how to call a function properly to response

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

Answers (2)

inu
inu

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

Maximiliano Poggio
Maximiliano Poggio

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

Related Questions