Uploaded image for project: 'Realm JavaScript SDK'
  1. Realm JavaScript SDK
  2. RJS-399

Realm with asynchronous callback in a write block does not keep write block open until promise is resolved

    • Type: Icon: Task Task
    • Resolution: Fixed
    • Priority: Icon: Unknown Unknown
    • None
    • Affects Version/s: None
    • Component/s: None

      Goals

      I want to write asychronous code inside of a write transaction. I need to read a prepare a media file using a service object, and then pass that information to a database writing object. Something like

          databaseManager.realm.write(async () => {
            const card = databaseManager.realm.objects('Flashcard')[0]; // no problem
            await mediaManager.createMediaItem(card, media, true, true); // does not await
            console.log('1');
          });
          console.log('2');
      

      In that mediaManager object, I prep the file and then make a database write under the hood

      const fileData = await this.saveImageFromInput(media); // await necessary
          databaseManager.createMediaItemOnClient({ // create object happens inside this call
            clientId: Date.now(),
            flashcardId: card.clientId,
            isFront,
            mediaHash: filenameFromPath(fileData.path),
            updatedAt: new Date(),
          });
      

      Expected Results

      I expected that the realm.write would leave the write transaction open until all of the code inside had executed. Essentially, in the above code (first blocK), the console.log(1) would execute before the console.log(2). This would leave the write transaction open for all of the writes and reads that internally called methods might use.

      Actual Results

      The console.log(2) statement showed before the {{console.log(1)}}statement. Then of course, I get the classic:

      YellowBox.js:71 Possible Unhandled Promise Rejection (id: 0):
      Error: Cannot modify managed objects outside of a write transaction.
      Error: Cannot modify managed objects outside of a write transaction.
          at sendRequest (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:116463:35)
          at Object.callMethod (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:116213:18)
          at Realm.<anonymous> (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:115989:20)
          at Realm.create (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:115679:23)
          at _callee5$ (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:114894:29)
      ...
      

      This is because the write block is closed by the time the create actually executes.

      Steps to Reproduce

      Create any async write block for a realm write transaction like the above.
      Inside that transaction, include something like a sleep timeout and then a DB write, and try to await that write.
      The write should fail because the transaction should already be closed.

      • Realm JS SDK Version: 3.3.0
      • Node or React Native: React Native version 0.61.4
      • Client OS & Version: iPhone 10 simulator
      • Which debugger for React Native: Chrome

            Assignee:
            Unassigned Unassigned
            Reporter:
            unitosyncbot Unito Sync Bot
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: