In angular design there is no out of the box quick go to solution for data persistence through routing actions, furthermore persisting data to back-end server through API.
The project uses Mock REST API which you can download, then run the mock server, no any advanced configuration required.
The process of creating and setting up the project to create the component is not in the context of this article. But you can check the code at this GitHub repository or clone to test it locally.
It has two components, todos(Showing the list of todos) and new-todo(for adding a new todo item). They are routed using angular routing and styled using bootstrap and some custom CSS. The todos component loads the list of todos from the API and can delete the item on the list on clicking delete button.
And the new to-do component has a form to enter a new to do and then add via the API post call
In the repository there are four branches, each one with a different method. The master branch that has the components views and logic, dependencies, and foundational logic all implemented, then the branch with method that does not use state management at all, the branch with Angular @ngrx/store state management method, and then the magical @ngrx/data method.
Without State Management
For this method we only implement a service with add, delete and get to dos methods. These method will interact with the API and in our components, we will use DI to inject the service to the components and use the methods to communicate our component to the API. This has one drawback that got me searching for different implementation; every time we navigate to the new to do and back to to dos, the entire list is refreshed, a request is sent to the API, no good for user experience, and for bandwidth and memory. The data is not persistent across components. The solution to this problem is @ngrx/store.
Using @ngrx State Management
Using @ngrx/store and @ngrx/effects we get both state management, data persistence across components and better yet, we extend the redux pattern implementation to API calls by using actions, reducers and effects. The steps to implementing this method are;
- initiate the store in the app module and create the app state - create the todo reducer, add the todo state and add the todo state to the app state - create the todo actions add, add success, load, load success, delete and delete success actions - define reducers for add-success, load-success and delete-success actions for updating the todo state - define the todo selector - dispatch the load todos action in todos component - connect the todos selector to todos object in the todos component - dispatch the delete action on delete press in the todos component - dispatch the add action on new todo component
It is very tedious and has a lot of code. But with it comes the persistence, now the list of todos will only be requested from API once, when the load actions is dispatched for the first time, the consequent calls will fetch from the store and not make another request. Now each time we navigate to new to do route and back to the todos route, the list doesn’t flicker. And when a new to do is added or any is deleted, the API request will be sent and the store will be updated, without fetching the entire list from API.
The @ngrx/data method
The @ngrx/data method uses the package by the same name. This package abstracts reducers, selectors, actions, effects and states implementation code used in the previous method. It is best for applications with many repetitive CRUD operations. Makes the whole implementation simple for us, by implementing all standard REST API methods, and then allowing us to only extend the implemented class. The steps are:
- create global entity metadata, define the root URL as default config for entity config and add it to the entity for root config in app module - modify todo service to extend entity collection base - use the todo service to manipulate data in the todos and new todos components
This method is very straightforward, no need to create and define methods in services, but you get all REST methods, no need to define the stores, the reducers, actions, selectors etc. Everything is done behind the scene, and it very flexible as well if need to customize for a certain project, everything is well documented in the @ngrx site.
The @ngrx/data implementation is perfect for applications that have many CRUD applications, using the library will ensure that the user experience is very consistent across the application, speed up development time, reduce debug time, maintenance and scaling are also assured out of the box.
The source code for this article is available in GitHub.