Source:  Twitter logo

I have the following block of code:

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      avatar: '',
      ...some more data...
      }

      this.fetchUser = this.fetchUser.bind(this);
  }

  render() {
    return (
      <div>
        <SearchBox onSubmit={this.fetchUser}/>
        <Card data={this.state} />
        <BaseMap center={this.state.address}/>
      </div>
    );
  }

  componentDidMount() {
    function fetchUser(username) {
      let url = `https://api.github.com/users/${username}`;

      this.fetchApi(url);
    };

    function fetchApi(url) {
      fetch(url)
        .then((res) => res.json())
           .... some data that is being fetched .... 
        });
      };

    let url = `https://api.github.com/users/${this.state.username}`;
  }
}

export default App;

However, I get a TypeError: Cannot read property 'bind' of undefined for the following line: this.fetchUser = this.fetchUser.bind(this); in the constructor where I bind the function to this.

How can I make the function, which is inside componentDidMount method, visible and available for binding?

EDIT:

The reason I'm putting the functions inside componentDidMount was because of a suggestion from another user on StackOverflow. He suggested that:

@BirdMars that because you don't really fetch the data in the parent, and the state doesn't really hold the address object. call the fetch in componentDidMount of the parent and update the state there. this will trigger a second render that will pass in the new state with the address object (the first render will be with an empty state.address of course until you finish the fetch and update the state)

There is some fundamental misunderstanding here, you can still call the functions inside componentDidMount, however you should not define them inside it.

Simply define the functions outside componentDidMount and this will solve your problems, here is a short example

componentDidMount() {
   this.fetchUser(this.state.username);
}

function fetchUser(username) {
   let url = `https://api.github.com/users/${username}`;
   this.fetchApi(url);
};

function fetchApi(url) {
   fetch(url)
   .then((res) => res.json())
      .... some data that is being fetched .... 
   });
};
17 users liked answer #0dislike answer #017
Lyubomir profile pic
Lyubomir

Its a simple matter of scope:

function outer(){
  function inner(){
  }
}
inner(); // error does not exist

As birdmars suggested you should call this.fetchUser() inside component did mount. but declare the function outside!

class App extends Component {

  render() {
    return (
      <div>
        <SearchBox onSubmit={this.fetchUser}/>
        <Card data={this.state} />
        <BaseMap center={this.state.address}/>
      </div>
    );
  }
  fetchUser(username) {
      let url = `https://api.github.com/users/${username}`;

      this.fetchApi(url);
    };

  fetchApi(url) {
      fetch(url)
        .then((res) => res.json())
           .... some data that is being fetched .... 
        });
      };
  componentDidMount() {
    let url = username; //frome somewhere, most probably props then use props Changed function instead!
    var user = his.fetchUser(url)
    this.setState(() => {user: user});

  }
}

export default App;
2 users liked answer #1dislike answer #12
Joel Harkes profile pic
Joel Harkes

If you declare the functions inside componentDidMount they are only visible in that scope and get be accessed by the component itself. Declare them in your component. What he was talking about in this post was to call the functions from componentDidMount, but not to declare them in there.

1 users liked answer #2dislike answer #21
justadudewhohacks profile pic
justadudewhohacks

"Another guy from StackOverflow" suggest you to call functions in componentDidMount() method, but not to define them there.

So you should do this instead

class App extends Component {
    constructor(props) {
        ...
        this.fetchUser = this.fetchUser.bind(this);
        this.fetchApi= this.fetchApi.bind(this);
    }
    ...
    fetchUser(username) {...}
    fetchApi(url) {...}

    componentDidMount() {
        this.fetchUser(...);
        ...
    }
}
0 users liked answer #3dislike answer #30
lankovova profile pic
lankovova

Copyright © 2022 QueryThreads

All content on Query Threads is licensed under the Creative Commons Attribution-ShareAlike 3.0 license (CC BY-SA 3.0).