0

Hopefully this is easy for someone...but I am getting stuck here. I am looking to map over a constant. One of the things I am wanting to map over is an onPress function...so in my constant I am including what I would like this function to be, but am having trouble with "this". The example should make the most sense...any help is appreciated on how to set this up correctly. I am using React Native, but I'm sure same principle applies to React.

const ITEMS = [
  { title: 'Item 1', subTitle: 'Click here for Item 1 function', onPress: () => this.function1() },
  { title: 'Item 2', subTitle: 'Click here for Item 2 function', onPress: () => this.function2() }
]

class Page extends Component {
  function1 = () => {
    console.log('This is function 1');
  }

  function2 = () => {
    console.log('This is function 2');
  }

  render() {
    return (
      <View>
          {_.map(ITEMS, (item, itemIndex) => {
            return (
              <Item
                key={itemIndex}
                title={item.title}
                subTitle={item.subTitle}
                onPress={item.onPress}
                index={itemIndex}
              />
            );
          })}
      </View> 
    );
}

export default Page;

The error I continue to receive is:

_this.function1 is not a function

Does anybody know how I can set this up properly? Thanks!

Ridge Robinson
  • 738
  • 1
  • 8
  • 19
  • this is underscore.js `_.map` ? You can use js map. – Etherealm Jun 28 '17 at 19:53
  • It is actually lodash! – Ridge Robinson Jun 28 '17 at 19:54
  • You can use `ITEMS.map ( (item,itemIndex) => {})` – Etherealm Jun 28 '17 at 19:56
  • I just tried using that instead of lodash, and I received the same error...Can you elaborate a bit on what you meant? Perhaps I set it up wrong. – Ridge Robinson Jun 28 '17 at 19:58
  • Can you create a fiddle for the code ? It's very difficult to tell exactly why you are getting the error. I can see more than 2 possibilities. When you assign `onPress={item.onPress}` I think it calls the function as well. You need to bind it explicitly to 'this'. – Etherealm Jun 28 '17 at 20:05
  • I am not actually sure how to set up a fiddle appropriately for this example...I have made my example much simpler than it actually is, so it is difficult to try to create a fiddle. Would you have another suggestion I could try? Where should I be binding to 'this'? Right there in the onPress? Such as onPress={item.onPress.bind(this)} – Ridge Robinson Jun 28 '17 at 20:13

1 Answers1

4
  1. For React Native, you can just use ITEMS.map as user Envision commented.
  2. You are trying to use this outside of the Page class which means in its context, function1() and function2() do not exist. Notice that if you move const ITEMS inside the Page class, say inside render(), it will start to work.

    render() {
      const ITEMS = [
        { title: 'Item 1', subTitle: 'Click here for Item 1 function', onPress: () => this.function1() },
        { title: 'Item 2', subTitle: 'Click here for Item 2 function', onPress: () => this.function2() }
      ]
    
      return (
        <View>
          {ITEMS.map((item, itemIndex) => {
            return (
              <Item
                key={itemIndex}
                title={item.title}
                subTitle={item.subTitle}
                onPress={item.onPress}
                index={itemIndex}
              />
            );
          })}
        </View>
      )
    }
    

This is more of a basic Javascript understanding issue. To understand how to make your code do what you want, you should read about this and eventually how bind() works. This other StackOverflow answer may be of help too.

Michael Cheng
  • 9,644
  • 6
  • 46
  • 48
  • This is true...I did have this solution working as such previously. But I thought it was not as good practice to do it this way (by having the constant inside the render). But it does work, so I will accept the answer and look further into your links. thanks – Ridge Robinson Jun 28 '17 at 20:23
  • @RidgeRobinson With what `ITEMS` seems to stand for, it's probably not good practice to do it this way. It's just an illustration of the issue to show you what you need understand first before being able to fix your code. – Michael Cheng Jun 28 '17 at 20:26