0

I am facing a scope issue when calling a function inside componentDidMount. The function getArrival is defined outside componentDidMount. I tried a few things with no success.

What is the correct way to define getArrival so that I can access it inside the componentDidMount?

Thank you in advance.

Code:

getArrival = (lines) => {
    return fetch('https://api.tfl.gov.uk/Line/' + lines + '/Arrivals/' + nearestStopId)
      .then((response) => response.json())
      .then((arrivalData) => {

        }, function() {
          // do something with new state
        });
        console.log(arrivalData);
      })
      .catch((error) => {
        console.error(error);
      }
    );
  }

  componentDidMount() {
    // Variable to store user data
    let userLines = null

    // Variable to store nearest stop id
    let nearestStopId = null

    // Check all variables against the API
    for (i = 0; i < apidata.length; i++) {

      // Checks user stops id against beacon id
      if (userdata[i].bustopId == beaconId) {
        // Store match into variable
        nearestStopId = userdata[i].bustopId
        userLines = userdata[i].buses

        // matchStop(nearestStopId)

        break // Breaks the loop
      }
      console.log(userLines)
    }

    // Data for stops
    return fetch('https://api.tfl.gov.uk/StopPoint/' + nearestStopId )
      .then((response) => response.json())
      .then((stopData) => {

        let linesId = []
        let selectedLines = []

        console.log("linesId at this stop", stopData.lines)
        console.log("userlines", userLines)

        // Loop through the data in stopData
        for (i = 0; i < stopData.lines.length; i++) {
          // ... and add all buses id from the API to the array
          let currentLine = stopData.lines[i].id
          linesId.push(currentLine)

          // Checks if user lines are included in current lines ...
          if ( userLines.includes(currentLine) ) {
            // ... if so, push it into selected lines
            selectedLines.push(currentLine)

            getArrival(lines) // This gets an error not defined

            let lines = selectedLines.toString()
          }
        }

        console.log("selectedLines", selectedLines, "from ", linesId)

        let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
        this.setState({
          isLoading: false,
          dataSource: ds.cloneWithRows(selectedLines),
        }, function() {
          // do something with new state
        });
      })
      .catch((error) => {
        console.error(error);
      }
    );
  }
Diego Oriani
  • 1,647
  • 5
  • 22
  • 31

1 Answers1

2

I'm going to assume that the code you've shown creating getArrival is inside your class body, e.g.: (you've confirmed that now)

class YourComponent extends React.Component {
    getArrival = () => {
        // ...
    };

    componentDidMount() {
        // ...
    }

    // ...
}

If so, that's using the class properties proposal (not yet standard, but at Stage 3) and it creates a property on your instance (like this.getArrival = ...; in your constructor).

So you would access it on this:

    this.getArrival(lines)
//  ^^^^^

That code is in a callback (or two), but they all appear to be arrow functions, and so they close over this and will use the one componentDidMount was called with (which is the right one).

See this question's answers for why I checked that the callbacks were arrow functions, and what to do in cases where you can't use arrow functions for whatever reason.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875