0

I am having trouble creating an array of titles from an Axios response. The method getTitles(props) receives data from the Axios response. How do I create an array of titles dynamically?

The functions I have tried in Javascript are for loops and EC6 mapping, nothing seems to work. Being new to react I could be missing something but I am not sure what it is.

React code

export default class Featured extends React.Component {
  constructor() {
    super();
    this.state = {
      data: null,
   }
  }

  /**
   *  Received request from server
   */
  componentDidMount(){
    ApiCalls.articleData()
      .then(function(data){
        this.setState(function(){
            return {
              data: data
            }
        })
      }.bind(this));
  }

  getTitles(props){

    //-- What code do I place here?

    console.log(props.data)
    return ['test title', 'test title 2'];


  }

  /**
   *  Render request
   */
  render() {
    let dataResponse = JSON.stringify(this.state.data, null, 2); 
    const Articles = this.getTitles(this.state).map((title, i) => <Article key={i} title={title}/> );
    return (
        <div class="row">{Articles}
        <pre>{dataResponse}</pre> 
        </div>
    );
  }
}

Axios Code

var ApiCalls = {
  articleData: function(id){
    return axios.all([getArticles(id)])
      .then(function(arr){
        return arr[0].data.data;
      })
      .catch(function (error) {
        console.log(error);
      })
  },

enter image description here

2 Answers 2

1

React setState behaves asynchronously . Your articles get rendered before the ajax was called and was not re rendered due to asynchrony in setState.

This is what doc(https://reactjs.org/docs/react-component.html#setstate) says

setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall. Instead, use componentDidUpdate or a setState callback (setState(updater, callback)), either of which are guaranteed to fire after the update has been applied. If you need to set the state based on the previous state, read about the updater argument below.

You can render the article after successful ajax call like below

componentDidMount(){
    ApiCalls.articleData()
      .then(function(data){
        render(<Article data={data}/>, document.getElementById('...'));
      }.bind(this));
  }
Sign up to request clarification or add additional context in comments.

Comments

0

Because of the post above, I was able to fix the issue by the code example below To see a working example goto the git repo

  ApiCalls.articleData()
      .then(function(data){
        const newData = data.map(c => {
          return  c.attributes.title;
        })
        const addElement = newData.map((title, i) => <ContentTiles key={i} title={title}/> );
        const newState = Object.assign({}, this.state, {
           newData: addElement
        });
        this.setState(newState);
      }.bind(this));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.