something in ngrx (redux pattern) than I still dont get for large applications

Viewed 319

I've been building data driven applications for about 18 years and for the past two, I've been successfuly using angular for my large forms/crud based apps. You know, the classic sql server db with hundreds of tables with millons of records. So far, so good.

Now I'm porting/re-engineering a desktop app with about 50 forms, all complex, all fully functional, "smart". My approach for the last couple years was to simply work tightly with the backend rest API to retrieve, insert or update data as needed and everything works fine.

Then I stumbled across ngrx and I understand exactly how it works, what it does and why it is good for a "reactive" app.

My problem is the following: In the usual lifecycle of the kind of systems i mentioned, you always have to deal with fresh data and always have to tell everything to the server. Almost no data in such apps can be safely "stored" localy since transactional systems rely on centralized data interactions. There's no such thing as "hey lets keep this employee's sales here for later use".

So why would it be so important to manage a local 'store' when most of my data is volatile? I understand why it would be useful for global app data like user-profile or general ui related state, but for the core data itself? I dont get it. You query for data, plug that data in the form, it gets processed by the user and sent back to the server. That data is no longer needed, and if you do need it, you ask for it again, as it could have changed its state since the last time you interacted with it.

I do not understand the great lengths i have to go to mantain a local store and all the boilerplate if that state is so volatile.

They say change detection does not scale but I've build some really large web apps with a simple "http service" pattern and it works just fine, cause most of the component-tree is destroyed anyway as you go somewhere else in the app, and any previous subscriptions become useless. Even with large-bulky-kinky forms, it's never that big of a problem the inner workings of a form as to require external "aid" fro a store. The way I see it, the "state" of a form is a concern of that form in that moment alone. Is it to keep the component tree in sync? never had problems with that before... even for complicated trees with lots of shared data, master detail is kind of a flat pattern in the end if al lthe data is there.

For other components, such as grids, charts, reporte, etc, same thing applyes. They get the data they need and then "puf", gone.

So now you see my mindset. I AM trying to change it to something better. Why am I missing out the redux pattern?

1 Answers

I have a bit of experience here! It's all subjective, so what I've done may not suit you. My system is a complex system that sounds like it's on a similar scale as yours. I battled at first with the same issues of "why build complex logic on the front end and back end", and "why bother keeping stuff in state".

A redux/NGRX approach works for me because there are multiple ways data can be changed - perhaps it's a single user using the front end, perhaps it's another user making a change and I want to respond to that change straight away to avoid concurrency issues down the track. Perhaps there are multiple parts within my front end that can manipulate the same data.

At the back end, I use a CQRS pattern instead of a traditional REST API. Typically, one might suggest to re-implement the commands/queries to "reduce" changes to the state, however I opted for a different approach. I don't just want to send a big object graph back to the server and have it blindly insert, and I don't want to re-implement logic on the client and server.

My basic "use case" life cycle looks a bit like:

  1. Load a list of data (limited size, not all attributes).
  2. User selects item from list
  3. Client requests "full" object/view/dto from server
  4. Client stores response in object entity state
  5. User starts modifying data
  6. These changes are stored as "in progress" changes in a different part of state. The system is now responding to the data in the "in progress" part
  7. If another change comes in from server, it doesn't overwrite the "in progress" data, but it does replace what is in the object entity state.
  8. If required, UI shows that the underlying data has changed / is different to what user has entered / whatever.
  9. User clicks on the "perform action" button, or otherwise triggers a command to be sent to server
  10. server performs command. Any errors are returned, or success
  11. server notifies client that change was successful, the client clears the "in progress" information
  12. server notifies client that Entity X has been updated, client re-requests entity X and puts it into the object entity state. This notification is sent to all connected clients, so they can all behave appropriately.
Related