Quantcast
Channel: Active questions tagged react-native+typescript - Stack Overflow
Viewing all articles
Browse latest Browse all 6287

React Native: which pattern is best for opening and closing Realm instance?

$
0
0

I need to persist lots of different data objects (nested, with relationships) that are used across several components with Realm (10.1.3) for a react native project (0.63.3).

My goal is to have a class that provides an API with read and write operations on Realm for all other modules, screens and so on. However I have trouble finding the right pattern for it.

Idea 1: Implement all operations in one place, open and close Realms each time

Write-Operations run smoothly:

export class RealmProviderSample {    static asnyc writeObject(object:ObjectType) {       const realm = await Realm.open(config);           realm.write(() => {                realm.create("ObjectType", object);           });        realm.close();     }  // ...}

However reading an object and closing the realm leads to Errors as the data cannot be used anymore when the realm is closed. I got stuck on trying to clone the realm object (I need a deep copy), but the clone is always empty. This seems to be a known problem: issue 2805, issue 1074

import { cloneDeep } from 'lodash';export class RealmProviderSample {    // ...    static async readObject() : Promise<Object> {        let object:Object = {}        const realm = await Realm.open(config)        const tmpReferencedObject = <Object> realm.objects("Object")         object = cloneDeep(tmpReferencedObject)          console.log(object) // object is empty {}         realm.close();        return tmpReferencedObject // Error "invalidated results" when using the returned object, because realm was closed    } }

This approach only works when the copy problem is solved (there is a solution for Swift. Encode in JSON and then Decode back is not working either, because the Realm object has relations (TypeError JSON.stringify cannot serialize cyclic structures)

Idea 2: Implement all operations in one place, manage a global realm instance

An alternative solution would be to have a global realm instance that is opened on the first use and closed, when the application is send to the background.

var realm:Realmexport class RealmProviderSample {    static asnyc writeObject(object:ObjectType) {        if (!realm || realm.isClosed) {            realm = await Realm.open(config);        }        realm.write(() => {            realm.create("ObjectType", object);        });    }    static async readObject() : Promise<Object> {        if (!realm || realm.isClosed) {            realm = await Realm.open(config);        }        return <Object> realm.objects("Object")     }    // call this when application goes to background?    static closeRealmIfOpen(){        if (realm && !realm.isClosed) {            realm.close();        }    }}

To me it is not clear whether it is a good idea to leave the realm open. In the docs it is stated that a realm should always be closed when not used.

Idea 3: Implement each operation where it is used, manage each realm separately

This the approach I can see in all the tutorials, but I have the feeling that it doesn't scale. Also most samples don't close the realms.

class MyScreen extends React.Component {    realm: Realm;    // constructor...    componentDidMount() {        this.realm = new Realm(config);        this.realm.write(() => {            this.realm.create("ObjectType", object);        });    }    componentWillUnmount() {        this.realm.close()    }    // render ...}

If data is used across several screens and components (some sub-data passed via Props) it might be difficult to close the instance safely.

I prefer idea one - but it doesn't work without the deep copy of a realm object. Did anyone solve this problem? Which pattern do you use and does it scale?


Viewing all articles
Browse latest Browse all 6287

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>