VassoG
VassoG

Reputation: 83

How to pass a property from a component to another to perform an ajax request in ReactJS?

I've recently started to study reactjs and I'm currently experimenting with ajax requests and passing properties from parent to children. I have a react component Competitions which performs an ajax request:

var Competitions = React.createClass({
 getInitialState: function() {
  return {
    compData: [],
  }
 },

 componentDidMount: function() {
  axios.get(this.props.source, {
    headers: {'X-Auth-Token': '*******************',
              'Content-type': 'application/json'}
  })
  .then(result => {
    this.setState({compData: result.data});
  })
  .catch(error => {
    console.log(error);
  });
 },

 render: function() {
  return (
    <CompTable compData={this.state.compData} />

  );
 }
});

module.exports = Competitions;

The Competitions component passes the results data to CompTable

var CompTable = React.createClass({

 propTypes: {
  compData:   React.PropTypes.array.isRequired
 },

 handleClick: function(e) {
  var url = 'http://api.football-data.org/v1/competitions/x/teams';
  var source = url.replace(url.split('/')[5], e);
  console.log(source);
 },

 render: function() {
  var list = this.props.compData.map(function (comp, i) {

   return (
    <tr key={i+1}>
     <th scope="row">{i+1}</th>
     <td className={comp.id} onClick={this.handleClick.bind(this, comp.id)} >{comp.caption}</td>
    </tr>
   );
  }, this);
  return (
   <tbody>{list}</tbody>
  )
 }
});

module.exports = CompTable;

This is the Teams component

var Teams = React.createClass({
 getInitialState: function() {
  return {
   teamData: [],
  }
 },

 componentDidMount: function() {
  axios.get(this.props.source, {
   headers: {'X-Auth-Token': '*******************',
            'Content-type': 'application/json'}
   })
   .then(result => {
    this.setState({teamData: result.teams.data});
   })
   .catch(error => {
    console.log(error);
   });
  },

  render: function() {
   return (
    <TeamsTable teamData={this.state.teamData} />,
   );
  }

 });


 module.exports = Teams;

What I'm trying to do is take on click the compData.id property of the CompTable component with a handleClick function and use it as a source property on another component named Teams (identical with the Competitions component) that uses the given property as a source url in order to perform a new ajax request. Is there a way to do that? Thank you

Upvotes: 1

Views: 107

Answers (1)

VassoG
VassoG

Reputation: 83

I think I found a solution to my problem. So, Competitions is the Parent and CompTable and Teams are the children. I don't know if there is a simpler way, but this one seems to work. It's not perfect, I have other problems to solve, but I managed to make a second ajax call inside a child component using my first ajax call inside the parent component, by grabbing the compData.id property and passing it to the children, on click. Any comments are welcome.

Competitions component

var Competitions = React.createClass({
 getInitialState: function() {
  return {
   compData: [],
   id: "",
  }
},

 componentDidMount: function() {
  axios.get(this.props.source, {
   headers: {'X-Auth-Token': '********************',
              'Content-type': 'application/json'}
  })
  .then(result => {
   this.setState({compData: result.data});
  })
  .catch(error => {
   console.log(error);
  });
 },

 changeId: function (newId) {
  this.setState({
   id: newId
  });
 },

 render: function() {
  return (
   <CompTable compData={this.state.compData} id={this.state.id} onClick= {this.changeId} />
  );
 }
});

module.exports = Competitions;

CompTable component

var CompTable = React.createClass({

 propTypes: {
  compData:   React.PropTypes.array.isRequired
 },

 getInitialState: function() {
  return {
   showTeams: false,
   hide: false,
  };
 },

 teamsClick: function() {
  this.setState({
   showTeams: true,
   hide: true,
  });
 },

 handleClick: function(e) {
  this.props.onClick(e);
 },

 render: function() {
  var list = this.props.compData.map(function (comp, i) {

   return (
    <tr key={i+1}>
     <th scope="row">{i+1}</th>
     <td className={comp.id} onClick={function() { this.teamsClick(); this.handleClick(comp.id); }.bind(this)}> {comp.caption} </td>
     <td>{comp.league}</td>
     <td>{comp.numberOfTeams}</td>
    </tr>
   );
  }, this);
  return (
   <div > { this.state.showTeams ? <Teams id={this.props.id}/> : null } </div>
   <tbody>{list}</tbody>
  )
 }
});

module.exports = CompTable;

Teams component

var Teams = React.createClass({

 getInitialState: function() {
  return {
   teamData: [],
  }
 },

 componentDidMount: function() {
  var url = 'http://api.football-data.org/v1/competitions/x/teams';
  var source = url.replace(url.split('/')[5], this.props.id);

  axios.get(source, {
   headers: {'X-Auth-Token': '********************',
            'Content-type': 'application/json'}
  })
  .then(result => {
   this.setState({teamData: result.data.teams});
  })
  .catch(error => {
   console.log(error);
  });
 },

 render: function() {
  return (
   <TeamsTable teamData={this.state.teamData}/>
  );
 }

});

module.exports = Teams;

Upvotes: 1

Related Questions