Search code examples
react-nativerealmreact-navigation

realm.js - Accessing object of type Contact which has been invalidated or deleted with NO stack trace


Would (really) appreciate help on this one.
I have a realm listView which navigates away to a detailed view.
The detailed view is deleting the entry from the original list view and navigate back. I have registered listeners on the realm DB change to update the content of the list view.
Here is the code I'm using, which, after delete get an exception - "Accessing object of type Contact which has been invalidated or deleted" after the navigation occurs.
Does anyone have an idea why?
Also, it seems that the change listener (updateContactsFromDB) is called twice, while deleting just one object - ideas?

10x

ContactPage.js:

export default class ContactsPage extends Component {
  updateContactsFromDB(){
    console.log("ContactsPage:updateContactsFromDB()");
    let contacts = Realm.objects('Contact');
    this.setState({
      dataSource: this.state.dataSource.cloneWithRows(contacts.snapshot()),
    });
  }
  constructor(props) {
    console.log("ContactsPage:constructor()");
    super(props);
    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => (r1 !== r2)});
    let contacts = Realm.objects('Contact');
    this.state = {
      dataSource: ds.cloneWithRows(contacts.snapshot()),
    };
     this.updateContactsFromDB = this.updateContactsFromDB.bind(this);
  }
  componentWillMount(props){
    console.log("ContactsPage:componentWillMount");
    Realm.addListener('change', this.updateContactsFromDB);
  }
  componentWillUnmount(props){
    console.log("ContactsPage:componentWillUnmount");
    Realm.removeListener('change', this.updateContactsFromDB);
  }
  render() {
    console.log("ContactsPage:render()");
    return (
            <ListView
              dataSource={this.state.dataSource}
              renderRow={(contact) => (
                <TouchableOpacity onPress={ () => this.props.navigation.navigate('ContactNotesPage', { contact: contact}) }>
                  <Text>test Contact</Text>
                </TouchableOpacity>
              )
            }
            />
    );
  }
}

ContactNotesPage.js:

export default class ContactNotesPage extends Component {
  constructor(props) {
    console.log("ContactNotesPage:constructor");
    super(props);
  }
  render(){
    console.log("ContactNotesPage:render()");
    const { params } = this.props.navigation.state;
    return (
      <TouchableOpacity onPress={ () => {
          console.log("ContactNotesPage:delete");
            Realm.write(() => { Realm.delete(params.contact);});
            this.props.navigation.navigate('ContactsPage');
        }
       }>
      <Text>DeleteContact</Text>
      </TouchableOpacity>
    )
  }
};

// main.js
const MainStack = StackNavigator({
  ContactsPage: {
    screen: ContactsPage,
  },
  ContactNotesPage:{
    screen: ContactNotesPage,
  },
});

export default MainStack;

Solution

  • Seems like it's a bug in realm/react-navigation. when passing a parameter which is a realm object - if you delete this object your next navigation will fail. A bug is already open at https://github.com/realm/realm-js/issues/1031