1

in my render function I am trying to display the name of a company. Therefore I call a function getCompanyByShortlink where I want to assign a value company_name to this.company. I checked the response and it contains all data I need, so no problems here.

However this doesn't work, the value is not assigned. If I enter return this.company = "test"; directly, it works perfectly fine.

I would really appreciate if someone could help me to set the right value which comes from my API.

Thanks, Oliver

class Company extends React.Component {
   constructor(props){
   super(props);
   this.shortlink = this.props.shortlink;
   this.company = null;
}

getCompanyByShortlink(shortlink){
  //this works perfectly fine!
  // return this.company = "test";
  fetch('http://192.168.178.96:81/api/v1/companies/'+shortlink).then((response) => response.json())
  .then((responseJson) => {
  //this does not work for any reason.
  return this.company = responseJson.data.company.company_name;
})
  .catch((error) => {
    console.warn(error);
  });
}
render() {
  this.company =   this.getCompanyByShortlink(this.shortlink);
  return (
    <View style={styles.mainContainer}>
    <Text style={styles.mainWelcome}>Your Company: {this.company} </Text>
    </View>
    );
}

};

Oliver Franke
  • 35
  • 1
  • 1
  • 5
  • `this.company = this.getCompanyByShortlink(this.shortlink);` is setting this.company to a `promise` not the resolved value of the promise. – Ruan Mendes May 16 '16 at 14:47

3 Answers3

2

You should't do async ops in the render function. Try it this way:

class Company extends React.Component {
  constructor(props){
    super(props);
    this.shortlink = this.props.shortlink;

    this.state = {
      company: null
    };

    this.getCompanyByShortlink(this.shortlink).then((company) => {
      this.setState({company});
    });
  }

  getCompanyByShortlink(shortlink){
    //this works perfectly fine!
    // return this.company = "test";

    fetch('http://192.168.178.96:81/api/v1/companies/'+shortlink)
      .then((response) => response.json().data.company.company_name)
      .catch((error) => console.warn(error));
  }

  render() {
    return (
      <View style={styles.mainContainer}>
      <Text style={styles.mainWelcome}>Your Company: {this.state.company} </Text>
      </View>
      );
  }
}
  • Yes the correct way to force a re-render is by setting state. Beyond that, an explanation that the OP's code is mixing sync and async would help. That is, the OP's `getCompanyByShortlink` does not return a value, it returns a promise and the OP's code assumes it returns a value. – Ruan Mendes May 16 '16 at 14:45
  • Thanks a lot! I got it solved! This is also very helpful: https://facebook.github.io/react-native/docs/tutorial.html#render-a-movie Cheers – Oliver Franke May 16 '16 at 15:05
0

I'm not sure, but your return statement is return with a lexical this, which first of all I mean is bad programming practise. You could set something like this.that = that and then return that. You are also setting a assignment inside the return which could mean side-effects. It could come from that. If someone has pros against this please speak out!

Even Stensberg
  • 488
  • 5
  • 17
0

you need to setState to re-render the app to display the value. You can call

this.setState({ company: responseJson.data.company.company_name})

and in your render() function set Your Company: {this.state.company}

Also make the call to the function getCompanyByShortlink() on componentDidMount() instead of inside of the render() method. Because render method is called for every state update, so it might get called multiple times as you add more functionality to your component.

and you will be good to go.

Aakash Sigdel
  • 9,060
  • 5
  • 33
  • 38