How to use realm with async fetch request?

1.9k Views Asked by At

I have meet this situation for my requirements:

step 1. save data to local db which in the mobile phone (realm)

step 2. upload the local data to the server, and the server will return the data ids if success step 3. delete the records in local db by the returned ids which get by step2

Realm.open({schema:[MySchame],encryptionKey:getRealmKey()})
        .then(realm =>{
            realm.write(() => {
                // 1. get all step data from db
                let objetcs = realm.objects('MySchema');
                // 2. upload obtained data to server
                if(objetcs.length > 0){
                    let recordArr = [];
                    for (let o of steps){
                        recordArr.push(o.get());
                    }
                   uploadDataToServer(recordArr,(res)=>{
                        //3. filter the uploaded steps and delete them
                        let uploadedSteps = realm.objects('MySchema').filtered('id=$0',res.id);
                        if(uploadedSteps.length > 0){
                            realm.delete(uploadedSteps);
                        }
                    });
                }
            });
            realm.close();
        })
        .catch(error =>{
            console.log(error);
        });

but this is not works as expected, it seems DB is closed too early than networks success callback. Thanks for any ideas.

2

There are 2 best solutions below

2
On BEST ANSWER

First create a service like one below

import repository from "./realmConfig";

let CatalogsService = {
    findAll: function () {
        return repository.objects("CatalogsModel");
    },

    save: function (catalogs) {
        repository.write(() => {
            repository.create("CatalogsModel", catalogs);
        });
    },
    delete: function () {
        repository.write(() => {
            let all = repository.objects("CatalogsModel");
            repository.delete(all);
        });
    },

    update: function (catalogs, callback) {
        if (!callback) return;
        repository.write(() => {
            callback();
            catalogs.updatedAt = new Date();
        });
    }
};

module.exports = CatalogsService;

where my realmConfig file is as

import Realm from "realm";

class CatalogsModel extends Realm.Object { }
CatalogsModel.schema = {
    name: "CatalogsModel",
    primaryKey: "id",
    properties: {
        id: "string",
        name: "string",
        url: "string",
        status: "int"
    }
};
class OffersModel extends Realm.Object { }
OffersModel.schema = {
    name: "OffersModel",
    primaryKey: "id",
    properties: {
        id: "string",
        name: "string",
        url: "string",
        status: "int",
        machineId: "string",
        machineName: "string"
    }
};

export default new Realm({
    schema: [CatalogsModel, OffersModel],
    schemaVersion: 1,
    deleteRealmIfMigrationNeeded: true

});

Now import Service.js where you are calling async server call and do your job. For reference see below code

import CatalogService from './path/to/CatalogService .js'

//get objects
var catalogs = CatalogsService.findAll();

// fire async function , I prefer axios for network calls

Axios.post("SERVER_URL", {
        data: catalogs
    })
    .then(function (response) {
        if (response.success)
            CatalogsService.delete()
    }

I assume you can easily modify findAll() and delete() method as per your need

2
On

Finally ,I use realm like this:

let realm = new Realm({schema:[JOB_SCHEMA.jobTrack],encryptionKey:getRealmKey()});
        let objects = realm.objects('JobTrack');
        realm.beginTransaction();
        realm.delete(objects);
        realm.commitTransaction();
        realm.close();