Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

realm js: Access to invalidated Results objects

Tags:

realm

realm-js

I use realm inside my React native application a try to query list of objects from realm db.

function* loadPlaces() {
    let realm;
    try {
        const filter = yield select(getFilter);
        realm = yield call(Realm.open, {schema: [PlaceSchema]});
        let places = realm.objects(PlaceSchema.name);
        if (filter.search) {
            places = places.filtered("name CONTAINS $0", filter.search);
        }
        switch (filter.sort) {
            case Sort.BY_NAME:
                places = places.sorted('name');
                break;
        }
        yield put(loadPlacesSucceed(places));
    } catch (e) {
        console.warn(e.message);
    } finally {
        if (realm) {
            realm.close();
        }
    }
}

After that I use resulted data in flatlist:

<FlatList
        data={this.props.items}
        keyExtractor={(item) => '' + item.id}
        renderItem={({item}) =>
            <PlaceItem item={item} onClick={(item) => this._onItemClicked(item)}/>}/>

And receive error:

Access to invalidated Results objects.

If i remove realm.close() error disapear, but I need to close realm after query.

like image 762
Dmitry Ermichev Avatar asked Oct 15 '18 07:10

Dmitry Ermichev


2 Answers

Why do you think you need to close Realm after a query? If you close your Realm, you lose access to all auto-updating collections, such as Results, so you shouldn't close your Realm as long as you need access to a specific Results instance.

like image 136
Dávid Pásztor Avatar answered Oct 29 '22 14:10

Dávid Pásztor


It happens because as soon as the realm is closed, all access to data, which in current case is Results, is lost.

However as mentioned by OP "not close it at all" is not a good approach. Ideally it should be closed. You can see the official documentation says,

// Remember to close the realm when finished.

So what you can basically do is, open realm in componentDidMount and close it in componentWillUnmount.

Like,

componentDidMount() {
    Realm.open({
        schema: [{ name: 'SCHEMA_NAME', properties: { name: 'string' } }]
    }).then(realm => {
        this.setState({ realm });
    });
}

componentWillUnmount() {
    // Close the realm if there is one open.
    const { realm } = this.state;
    if (realm !== null && !realm.isClosed) {
        realm.close();
    }
}
like image 4
gprathour Avatar answered Oct 29 '22 13:10

gprathour