Angular Dashboard starterkit template: CRUD’ing it
If you haven’t read my first article about my Angular Dashboard starterkit template, I suggest to read it first:
As a side project, I’ve also created a repository with a stripped down version of my Starterkit. Most of the patterns in this article can also be applied:
So are you ready? Oh a little warning, this can be a very long read :) #sorryNotSoSorry
Now that we found “authentication” what are we gonna do … with it?
When I started my starterkit, my main focus was to demonstrate some coding patterns in Angular on authentication (login,logout,validate). But then I realised, so now that I’ve demonstrated how to create a simple dashboard, you also want to do epic sh$t in the secured dashboard environment.
So I came up with an feature called “Items”. Basicly it’s just a collections of items and each item has the following properties:
- title
- description
This article is to demonstrate CRUD (Create / Read / Update / Delete) pattern and also some component structuring.
It’s all about components
When I transitioned from AngularJS to Angular I kept asking other developers: “what is different between AngularJS and Angular?”. And the same answers always comes up : “it’s all about components”. Components are reusuable. And with Angular you need to think as a component.
But when I started with a simple list, I ofcourse started Googling on how to create a list with items. This list is populated by an array of objects and the list is rendered in the view using *ngFor. So a typical example you get is something like this:
This will produce a list with items. Nothing really fancy, this just works. But remember .. it’s all about components! So let’s break this into 2 components:
- ItemsListComponent (wich will have the array with all the items), you can also see this as the parent.
- ItemsListItemComponent (a component with only one item, given from a parent component), you can see this as a child.
ItemsListItemComponent (child)
First we create the item component :
Notice the @Input() item: ItemModel; line. The @Input decorator will expose the variable to the outside world (outside of this component), so a parent component can bind to it and pass data. So let’s do that.
ItemsListComponent (parent)
The ItemsListComponent will still hold the array with items and will do the *ngFor , but instead of repeating the <li> elements, it will repeat the app-items-list-item component and will pass the item from the array into the app-items-list-item component (well .. it binds to it via property binding).
Why this pattern?
This way you have a better control (logic and layout) on the
- list (the parent)
- an item in the list (a child)
and you can reuse the components.
To even top it off, you now can now reuse the ItemsList component within other components, for example
CRUD components
So now we can create components that resembles the CRUD strategy :
- ItemAddEditComponent (Create or Update)
- ItemsList (Read)
- ItemEditComponent (Update)
- ItemsListItem (Delete, well it has a delete button to delete an item)
ItemAddEditComponent
So this component is a nice example about using reusing components. This component has 2 functions:
- Update
- Create
This components can accept an ItemModel object (through the @Input() decorator). When there is a ItemModel present, the internal save button will become a “update” and if not it will be a “create” button.
In my starterkit you will see this in action in the ItemEditComponent (this will pass a ItemModel to the ItemAddEditComponent) and in the ItemsComponent (wich will just include the ItemAddComponent without a ItemModel object).
Adding Service logic
So now we need actual logic. I’ve created a Items service to hold the data and interacting with the (Fake) backend API. Here you can also see the CRUD pattern used in the API calls.
HTTP Request Methods
Do actually send/recieve we rely on the HTTP Request Methods. The most common one are the GET and POST methods. But there are more methods we can use and even reflect the CRUD strategy:
- POST (Create) , this.http.post
- GET (Read), this.http.get
- PUT (Update), this.http.put
- DELETE (Delete), this.http.delete
The POST and PUT are a bit the same. Some use the POST for creating and PUT for updating and some use it reversed.
So how does that reflect the actual code?
Create
Here’s a snippet of creating/adding an item. As you can see we are using the POST method (this.http.post)
Read
Update
Delete
Using the TAP as side effect
You may have noticed that I used the TAP function in my Http requests. Tap will execute actions/sideeffects that are not “part” of the Observable stream. It will take the the result(s) of the MAP function, but it cannot alter the stream. You can then execute actions that have not direct effect to the Observable stream. In my case I will update/delete/insert items into the service internal storage.
Using a BehaviourSubject store
In my project I use a BehaviourSubject to store my items array. The BehaviourSubject is just like a normal Subject with some extra functionality:
- It can hold any value that is committed
- It can have an initial value
- Any subscribers that will subscribe to the BehaviourSubject will recieve the current value that the BehaviourSubject holds
So any modifications in the local service will go through the BehaviourSubject and all subscribers will get the newly updated data.
I’ve written a Medium post on this:
Well that’s it for now. Still have some more to write, food to eat, code to debug :)
You can find me on :
- linkedin : https://www.linkedin.com/in/fransjoleihitu/
- GitHub : https://github.com/fransyozef/
- Instagram : https://www.instagram.com/thehangrycoder/
- Twitter: https://twitter.com/thehangrycoder