Darsshan
Darsshan

Reputation: 956

Passing values to functions in React Native from Array

I am extracting data from a JSON Array and creating objects out of it and setting the string values that I need from the array within the objects I am creating using a for loop:

var gamesList = [];
gamesList = this.props.navigation.state.params.gamesList;
var gameIconList = [];

for(var i=0;i<3;i++){
  var provider = gamesList[i].provider;
  var gameId = gamesList[i].gameId.toString();

  gameIconList.push(
    <TouchableOpacity onPress={(provider,gameId) => this.launchGame(provider,gameId)}>
      <ResponsiveImage source={{uri: gamesList[i].imageUrl}}
      initWidth="200" initHeight="120" defaultSource={require('./splash-tile2.png')} />
    </TouchableOpacity>
  );
}

This is all happening within the render() function and the {gameIconList} will be called in the return() function as below:

return(
 <ScrollView horizontal={true}>
    {gameIconList}
 </ScrollView>
);

As you can see I am setting the string values into the onPress function call via the loop and when I click the image within the TouchableOpacity I want the string values I am setting to be sent back to the function above which is:

  launchGame = (provider, gameId) => {

  params = {
    Provider: provider.nativeEvent.text,
    Platform: this.state.Platform,
    Environment: this.state.Environment,
    GameId: gameId,
    IsDemo: this.state.IsDemo
  };

  request = {
    method: 'POST',
    headers:{
      "Content-Type": "application/json"
    },
    body: params
  };

}

But the problem is I have tried so many different methods and I always end up getting a Proxy object sent back to me when it comes to the provider value and an undefined sent to me when it comes to the gameId value.

I have tried the calling method of event.target.value and event.nativeEvent.text but to no avail.

What am I missing? And if this is not the correct way of sending values to the function, can I get a guide on how to do it properly?

Upvotes: 1

Views: 3679

Answers (1)

squgeim
squgeim

Reputation: 2351

The onPress prop for TouchableOpacity takes a callback function that is called when that element is "pressed".

This function is supposed to be an event handler. It is conventional that an event handler is called with an event object. I think you are misunderstanding how callback functions are called. Please go through this.

So, your function is called with the event object (proxy event object in React) in the first argument and undefined as the second argument.

Do this instead:

<TouchableOpacity onPress={() => this.launchGame(provider, gameId)}>

But there is more. This probably won't work properly because of how closures work. See here.

Basically, you are changing the value in provider and gameId on each loop. The callback functions have these variables in its closure, but they do not store the exact value that was there when these functions were defined (basically, you'll get the last value stored in provide and gameId when pressing on all of the TouchableOpacity). This is also because you are using var, instead of let or const, which had function scope and not block scope.

You can do this instead:

<TouchableOpacity onPress={() => {
  var provider = gamesList[i].provider;
  var gameId = gamesList[i].gameId.toString();
  this.launchGame(provider, gameId)
}}>
  <ResponsiveImage
    source={{uri: gamesList[i].imageUrl}}
    initWidth="200"
    initHeight="120"
    defaultSource={require('./splash-tile2.png')}
  />
</TouchableOpacity>

This way you are defining these variables in each callback's scope directly. (Or, if you can use let or const, change var to const when defining provider and gameId and your code should work.)

Upvotes: 5

Related Questions