0

I'm experimenting with mobx state management, and I am wondering how this can be used for vanilla javascript code that is not inherently reactive, and has nothing to do with UI.

For example: In an app several queries may be executed as soon as the app loads, but the server may not yet be ready to handle these queries or their results yet. To avoid race conditions we queue the queries and then execute them asynchronously when the ready state has changed.

I know how I would handle this in flux/redux because that model is very simple and totally environment agnostic. But in mobx the only way I know of making something reactive, is using the observer decorator, which is only useful in reactjs. Ostensibly, observer is just wrapping my reactjs class in an aoutrun function, but I can't quite wrap my head around how it is being done, or how I might mimic the behavior for my use case. What I would like is to be able to do something like this

class ServerState {
    @observable ready = false
    @action
    changeReadyState(state) {
        this.ready = true
    }
}

const state = new ServerState()

class DataLoader {
    queue = []

    loadData(id) {
        if(state.ready) {
            Sql.query('select * from data where id = ' + id)
        } else {
            queue.push(id)
        }

        // this needs to happen as soon as the ready state changes
        processEnqueuedQueries() {
            for(let id of queue) {
                this.loadData(id)
            }
        }
    }

The best I've come up with so far is using a pub/sub model similar to flux, and publishing the new ready state in an autorun on the ServerState class. This doesn't really take advantage of the reactiveness that mobx brings to the table though. So how do I react to a change in an observable property of one class, in another?

richbai90
  • 4,175
  • 3
  • 35
  • 73

1 Answers1

0

I figured it out. Mobx autorun observes observables regardless of where they come from, that are used within the function. So the following is what I came up with

class ServerState {
    @observable ready = false
    @action
    changeReadyState(state) {
        this.ready = true
    }
}

const state = new ServerState()

class DataLoader {
    queue = []

    constructor() {
        autorun(() => {
            if(state.ready) {
                this.processEnqueuedQueries()
            }
        })
    }

    loadData(id) {
        if(state.ready) {
            Sql.query('select * from data where id = ' + id)
        } else {
            queue.push(id)
        }

        // this needs to happen as soon as the ready state changes
        processEnqueuedQueries() {
            for(let id of queue) {
                this.loadData(id)
            }
        }
    }
richbai90
  • 4,175
  • 3
  • 35
  • 73