0

I'm on react native and I'm unsure how to use prepareUpdate is it okay to do the following?

const oldChannel = await getChannel('asdf')
const prepareChannel = (x: Channel) => {
  x._raw.id = 'asdf'
  x.parent!.id = 'test'
}
const preparedChannel = oldChannel
  ? oldChannel.prepareUpdate(prepareChannel)
  : channelsCollection.prepareCreate(prepareChannel)
await doSomeAsyncWork()

await database.write(() => database.batch(preparedChannel))

From the source code it says

// After preparing an update, you must execute it synchronously using
// database.batch()

Additionally at some point I'm pretty sure I got the error record.prepareUpdate was called on ${this.table}#${this.id} but wasn't sent to batch() synchronously -- this is bad! but I'm no longer able to reproduce that error also I have no idea how I got it because I'm on react native and process.nextTick is not defined which is needed for the error to appear.

https://github.com/Nozbe/WatermelonDB/blob/44d89925985aca3fa72eef1df78f89356b1d9b6f/src/Model/index.js#L118

david_adler
  • 9,690
  • 6
  • 57
  • 97

1 Answers1

0

From https://watermelondb.dev/Writers.html#batch-updates, there's this example:

class Post extends Model {
  // ...
  @writer async createSpam() {
    await this.batch(
      this.prepareUpdate(post => {
        post.title = `7 ways to lose weight`
      }),
      this.collections.get('comments').prepareCreate(comment => {
        comment.post.set(this)
        comment.body = "Don't forget to comment, like, and subscribe!"
      })
    )
  }
}

Notice the prepareCreate and prepareUpdate happen inside the writer (which happen all in the same context), so your code would be better written as:

const oldChannel = await getChannel('asdf')
const prepareChannel = (x: Channel) => {
  x._raw.id = 'asdf'
  x.parent!.id = 'test'
}

await doSomeAsyncWork()

await database.write(async () => { // <- function passed to the writer must be async
  const preparedChannel = oldChannel
    ? oldChannel.prepareUpdate(prepareChannel) // <- prepare inside the same writer that the batch happens
    : channelsCollection.prepareCreate(prepareChannel) // <- prepare inside the same writer that the batch happens
  await database.batch(preparedChannel) // <- await batch
})
Lucas P. Luiz
  • 386
  • 1
  • 10