Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subscribe to substate? #26

Closed
Dimillian opened this issue Feb 27, 2017 · 1 comment
Closed

Subscribe to substate? #26

Dimillian opened this issue Feb 27, 2017 · 1 comment

Comments

@Dimillian
Copy link

I'm working on fairly complexe application, and I'm splitting my AppState into multiple substate, so I have multiple reducers and states. It works fine, but is there a way to subscribe to change only happening to a specific part of my state?

To get you an idea here is my AppState

class AppState {
    var userState = UserState()
}

and my UserState

class UserState {
    var currentUser: String? = null
    var users = mutableMapOf<String, User>()
}

and my AppReducer

class AppReducer: Reducer<AppState> {
    val userReducer = UserReducer()

    override fun reduce(state: AppState, action: Action?): AppState {
        userReducer.reduce(state.userState, action)
        return state
    }
}

So when I subscribe, I would want to do something like this:

store.subscribe { state.userState ->
  Log.d("State change", state.userState.currentUser)
}

is that something possible or planned?

Thanks!

@brianegan
Copy link
Owner

Hey there :) Sorry for the delay -- haven't been checking in too actively on this project as of late. We don't have built-in support, but I could see this being achieved pretty easily with a little helper class that looks something like:

class CurrentUserSubscriber(val store: Store<AppState>) {
    fun subscribe(subscriber: (User?) -> Unit): Subscription {
        val subscription = store.subscribe {
            // Use this part of the function to narrow down to the part of the state you care about
            subscriber(it.userState.currentUser)
        }

        return Subscription { subscription.unsubscribe() };
    }
}

This would be used like so:

@Test
    fun `store should be able to subscribe to substate`() {
        val reducer = Reducer<AppState> { state, action ->
            when (action) {
                is User -> state.copy(userState = state.userState.copy(currentUser = action))
                else -> state
            }
        }
        val store = BaseStore(AppState(), reducer);
        var currentUser: User? = null

        // Create an instance of our Substate-Subscriber     
        val currentUserSubscriber = CurrentUserSubscriber(store)

        // Subscribe to the substate using our class
        currentUserSubscriber.subscribe { currentUser = it }

        val user = User("Brian")

        // Dispatch a new User to the store
        store.dispatch(user)

        // Shows that our substate subscriber worked!
        assertThat(currentUser).isEqualTo(user)
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants