Angular Rent Manager — Part 2
In the last post we saw how to setup the project and familiarize ourselves with some starter files. We also added CSS libraries and used them in our component. Now let’s see how we can make more changes to our base component. Let’s begin!
Changing our rent-list component
Remember how we created the rent-list
component in the last part. Now let’s add some sample data to it and see how we can display it in a table.
Go to the rent-list.component.ts
and add sample data in the RentListComponent
class.
Now let’s display it in rent-list.component.html
*ngFor
is a structural directive. This it can reshape the DOM’s structure by adding, removing or manipulating elements. You can think of it as a for loop for Angular. Here, it loops over the elements in rents_x
and displays them in a table. The tr
element is repeated in HTML. Go on, run ng serve -o
and you should see a table with the sample data.
But this method doesn’t seem very robust. What if one misses a data element in HTML or TS file? Maybe during code migration or application upgrade? How do we ensure there is some consistency and structure for our data?
Models
Models are nothing but certain structures that define how our data is supposed to be. It could be classes or interfaces with data elements. These can then be called upon and re-used so as to keep a check on the data flowing from one part of the application.
Make a new folder named models
under app
and add two files to it:
- rent-item.ts : this will hold the structure for every rent item like this month’s electricity meter readings, water bills etc (basically whatever varies every month, but the data points are known).
- rent-struct.ts : holds the basic rent components which do not vary over time (like base rent, maintenance cost etc) but are essential in calculating the final amount due.
The ?
in our constructor parameters means that these are optional parameters, we can skip them while calling the constructor. Note that if you have multiple optional parameters then they should come in after all the required parameters have been written. If it’s just one then it can come anywhere in between too.
getTotal()
and getElectricityRate()
will be used in our calculation logic.
Now that we have our models in place, let us include them in the component like this:
import { RentItem } from '../../models/rent-item';import { RentStruct } from '../../models/rent-struct';
Delete the rents_x
or comment it out. Then modify the RentListComponent
as follows:
export class RentListComponent implements OnInit
{
rent_a: RentItem = new RentItem(120, 100, 7, 2018, 19500, 19500, 0);
rent_b: RentItem = new RentItem(150, 120, 8, 2018, 19500, 19500, 0);
rents = [this.rent_a, this.rent_b];
constructor() { }
ngOnInit() { }
}
We leveraged out rent-item class to make an object with the desired values. Now in the HTML file change the name rents_x
to rents
which is nothing but an array of rent-item
objects now.
<tr *ngFor="let rent of rents">
Reload your application and the results should be unchanged. But now we have a more organized and structured way of handling our data.
Adding data
We now need a mechanism to enable us to add rent as well to the list we have so far. For that we need a form first.
Add the following in rent-list.component.html
This is a simple HTML using Materialize-CSS. [(ngModel)]
denotes two-way data binding. Meaning the value from this input field will be in sync with the data that we have in our TS file and associated with a particular variable name. Thus, we can keep the working logic and the UI part completely separate while coding but bind the data so that we don’t have to work back and forth for the same item.
On line 21, (click)=”submit()"
means that on the “click” event (on the button), it will call the submit
function that we will define in the TS file. This is one-way binding called as event binding.
Make some more modifications and the final TS file should look like this
Here we have also added a base rent object according to the rent-struct class
rentStruct: RentStruct = new RentStruct(12500, 8.5, 0, 300);
We are picking up the previous meter reading from the last record i.e. current meter reading of the last record. So in the constructor it is
this.meterPrev=this.rents[this.rents.length-1].meterCurr;
Similarly we can see what happens when submit
is clicked in the UI. We have a logic in place which calculates the electricity bill by meter readings difference with the rate per unit and adding it to the base rent total.
this.total = (this.rentStruct.getElectricityRate())*(this.meterCurr - this.meterPrev) + (this.rentStruct.getTotal())
Then we are simply pushing a new RentItem
object made from our input values to the rents
array. Note how we get the current month and year
(new Date()).getMonth(),
(new Date()).getFullYear(),
And that’s it! You should now be able to add new rent objects as data and see them in the application. The finished page now should be like this
That’s all for now!