kmg
kmg

Reputation: 519

Undefined is not an object(evaluating 'this.state.contacts.filter') in React Native

I'm a newbie in react native and I encountered the following problem while working on a sample chat app in android emulator.

Its showing the error

Undefined is not an object(evaluating 'this.state.contacts.filter')

in the line of code

let filteredContacts = this.state.contacts.filter(
       (contact) => {
          return contact.name.indexOf(this.state.search) !== -1;
       }
);

Here is the code I'm working on.

    componentDidMount() {
            this.setState({contacts : this.props.navigation.state.params.contacts});   


    render() {
          let filteredContacts = this.state.contacts.filter(
            (contact) => {
              return contact.name.indexOf(this.state.search) !== -1;
            }
          );
          return (
            <View style={styles.listContainer}>
                <TextInput style={styles.searchbar} placeholder="Search"
                  onChange={(search) => {this.setState({search: search, isContactSearch: true}); this.onSearchPress}} />
                {!this.state.isContactSearch && 
                  <FlatList
                    keyExtractor={(item, index) => index}
                    renderItem={this.renderFlatListItem}
                    data={this.state.historyContactList}  
                    ItemSeparatorComponent={this.renderSeparator}>
                  </FlatList>
                }
                {this.state.isContactSearch && 
                  <FlatList>
                    {filteredContacts.map((contact) => {
                      return <View key={contact.number}>{contact.name}</View>
                    })}
                  </FlatList>
                }
            </View>
          );
        }

Upvotes: 0

Views: 1279

Answers (2)

Aadi Droid
Aadi Droid

Reputation: 1739

Since componentDidMount is called after your render method your initial state value is not initialized! You can do 2 things here,

1) Set an initial value for your state params in the constructor if this is a one time setup you need!

2) If you want the state to update before every render you can copy the same code into componentWillMount/componentWillReceiveProps

Upvotes: 1

jevakallio
jevakallio

Reputation: 35950

The componentDidMount callback runs only after the first render, so the state you set there isn't available on the first render pass.

You can move the state initialization logic to constructor instead:

constructor(props) {
  super(props);
  this.state = {
    contacts: props.navigation.state.params.contacts
  };
}

Note that here we set the state using regular javascript assignment instead of setState, because the latter is asynchronous and not safe to call in the constructor. If you want to later modify the state, you'll need to use setState as you have now.

Upvotes: 1

Related Questions