DEV Community

Advanced Blazor State Management Using Fluxor, part 6 - Persisting State

Eric King on March 14, 2021

This is the sixth in a short series of blog posts where I will go beyond the introductory level and dig a bit deeper into using the Fluxor library...
Collapse
 
thomeijer profile image
Thomas Meijer

Thanks for the great series, I really enjoyed all six posts.

I was wondering how you would go about 'cross user state'. For example, if there are two users active at the same time, and a weather forecast was added by user 1, how would you notify user 2 that a weather forecast was added.

Would it be possible to use a Singleton store where all users can dispatch actions to and subscribe to application wide actions?

Collapse
 
mr_eking profile image
Eric King

FYI I added a simple example using SignalR to the repo for this series. It doesn't persist anything to a database (I'm trying to keep the project as simple as possible) but it does demonstrate how two clients can communicate via Actions. I'll add another blog post about it soon.

github.com/eric-king/BlazorWithFluxor

Collapse
 
thomeijer profile image
Thomas Meijer

That looks exactly like something I was looking for, thanks a bunch!

Collapse
 
mr_eking profile image
Eric King • Edited

Thanks for the kind words.

In this scenario, the application state is all located in the client, as it's a Blazor WebAssembly application. There's no shared Fluxor state at all, as each client has its own store.

If I were to add cross-client communication so that each client's state could be updated based on another client's actions, I don't think I would do it via Fluxor on the server. I would do it via SignalR on the server, and my "singleton store" would be a database.

User1 submits some change to the server (which gets stored in the database), and that process notifies the server's SignalR hub of the change. The SignalR hub broadcasts the change to all of the listening clients, which would include User2. And User2's listener then Dispatches the appropriate Action to update their Store and whatever UI changes are needed.

Collapse
 
padnom profile image
padnom • Edited

Great job and thx for that's!
I performed a similar approach but instead of have a save and load action.
I persist state, each time state changed and I load form local storage only when counter.state.value is null.

Collapse
 
mr_eking profile image
Eric King

I'm glad you got it working. There's probably a million ways to go about it.

But I do have a question... I'm wondering when Counter.State.Value is null? If Fluxor is initialized correctly, no State should ever be null. You provide a non-null initial State in the Feature.

Collapse
 
padnom profile image
padnom

You right. It was a shorthand to explain what I do
In my code I use it for display username (string)
var login = loginSate.Value.LoginBackOffice;
if (login.Status == EnumStateLogin.NotInstantiate)
{
return await loginSessionStorage.GetLoginAsync(); ;
}
return login;

Collapse
 
tailslide profile image
Tailslide

I made a little library to persist fluxor states.. you can find it on nuget under Fluxor.Persist or here:

github.com/Tailslide/fluxor-persist

Collapse
 
christianweyer profile image
Christian Weyer

Great article series, kudos!

I realize you are using a lot of XYZSuccessAction and XYZFailureAction types. And it seems like a common pattern. Wouldn't it be a good idea to have those in Fluxor as SuccessAction and FailureAction?

Thanks again.

Collapse
 
mr_eking profile image
Eric King

Thanks Christian.

It seems to me that there would be very limited value in a generic SuccessAction or FailureAction. Wouldn't you want to know what failed or succeeded, so you could react appropriately? If you only had a generic SuccessAction, then to know what succeeded you would need a payload of some sort identifying the Action that succeeded. To react to a particular success, you would have to handle the generic SuccessAction, which means processing every success and deciding whether to act on it by inspecting the payload.

I would much rather dispatch a specific XYZSuccessAction and be able to react to that specific action if necessary.

There's no reason you can't also dispatch a generic SuccessAction if you wish to do something generic upon every success, but I can't think of a reason I'd want to do that at the moment.

Collapse
 
1eyewonder profile image
1eyewonder

Thanks for a great series! It definitely helps my understanding when you have added so many simple examples that haven't been included in the other well-known tutorials. I would be interested in seeing if you could make an extra part to the series involving nested objects and avoiding any potential pitfalls