Building a CRUD Application with ag-Grid - Part 3
In Part 3 of this Series we create the scaffolding for our Angular application and get our data displayed in our first, simple, grid.
- Part 1: Introduction & Initial Setup: Maven, Spring and JPA/Backend (Database)
- Part 2: Middle Tier: Exposing our data with a REST Service
- Part 3: Front End - Initial Implementation
- Part 4: Front End - Grid Features & CRUD (Creation, Updates and Deletion)
In order for our data to be useful we need to make it available to users. So far we've exposed our data via REST service in the previous part, but now let's make it available to our users in the browser.
We'll be running an Angular application. One of the quickest way to spin up an Angular application is to make use of the Angular CLI, which we'll make use of here.
Scaffolding with Angular CLI
First things first, let's install Angular CLI. In our case we're going to install it globally as it's easier to use this way, but you can install it locally (i.e. local to your project) if you prefer.
Next we'll create a new Angular application in the root of the project:
Angular CLI will create a scaffolded project all ready to go - we can test it as follows:
You can now navigate to
http://localhost:4200/ and see the results of the scaffolding:
There are a number of ways you might structure your overall application - in this series we're going to keep the front and backends separate both in structure and in execution, at least when in development mode.
Doing so makes front end development easier and allows us to separate the two tiers (front and middle). We'll cover application packaging (into a single deployable artifact) later in the series.
We'll run the
front end code separately in development mode:
First Call to the Server
We'll make use of a simple Application architecture in the frontend:
As a first pass let's attempt to retrieve all Olympic Data from the server. In order to do that we're
going to break our front end application into further packages: one for our
model classes are pretty simple and are pretty much mirrors of their Java counterparts:
We'll also create a
AthleteService that will interact with our REST endpoint:
There's a fair bit going on here - we're creating a
Service that will make use of Angular's
Http service. In order to access it we use Angular Dependency Injection facility, so all we
do is specify it in our constructor.
findAll method we're providing an
Observable that will make a call to
REST endpoint, and on retrieval, map it to the model classes we created above. We actually get a lot of
from not too many lines of code here, which is great.
So far so good - let's plug this service into our application next:
We'll create a quick template to output our results:
Ok, great - we should be good to go now right? Unfortunately not - if we run both the front and backend as it stands we'll get the following error:
The problem here is that our Angular application is running in
localhost:4200, but our
application is running on
localhost:8080. The browser will by default prevent this due to
the risk of
malicious indirection - you can read more about CORS here, but for now we
an easy solution to this.
Let's head back to our
AthleteController.java controller and enable CORS:
With this one line we're good to go. Note that in a real application you'd probably want to only enable CORS for local development (perhaps with Spring profiles). You also want to be able to externalise the ports you run on via the use of properties.
Ok, let's try that again - let's start our applications and checkout the results:
Once both have started you can navigate to localhost:4200. You should see something like this:
Great, good progress so far - we now know we can call the backend successfully!
We're finally in a position to start hooking our data into ag-Grid!
First, let's install the ag-Grid dependencies - as we're going to be using a few of the Enterprise
that ag-Grid offers we'll install both the
If you're not using any of the Enterprise features then you only need to install the
ag-grid-angular is what allows us to talk to the grid and provides the rich Angular
We also need to let the Angular CLI know about the styles we want to use. In our demo we're going to use the Fresh Theme, but there are others available - please see the Themes Documentation for more details.
In order to let the CLI know about the styles we want to add we need to add them to the
file. Look for the styles section and add the following CSS entries:
styles.css is a style file generated by Angular CLI - you can either keep it or remove it.
won't be using it in our demo here.
Next we need to add the
AgGridModule to our application. We do this by adding it to our
We now have the ag-Grid dependencies all setup - our next step is to actually use ag-Grid to display some data.
Our Grid Component
Let's create a new component that will be responsible for displaying our data in ag-Grid:
This will create a new Angular component for us and automatically register it in our Angular module.
Let's open up our new Component and inject our
AthleteService as before. The
will be responsible for supplying data to the Grid. Later, it will also be responsible for updates &
We also need two properties for our component: one for row data and one for column definitions - at a minimum the grid require what columns you want in the Grid, as well as what data to display.
Finally, we'll hook into the
gridReady event from the Grid. We do this for two reasons:
to access the
ColumnApi and secondly to auto resize the columns on
And our view template looks like this:
Notice that this is where we're binding to the row data and column definitions, as well as hooking into
gridReady event. There are other ways of doing this, but this is clearer and more
from an Angular perspective.
As we're now using the
AthleteService in our Grid Component, we can remove it from
Finally, we can hook our component into
With this in place we can now run our application...but we don't see quite what we're hoping for:
The reason for this is pretty simple - both
Results are complex
They don't have a simple key-value relationship unlike the rest of the data.
We can fix this easily by making use of a Value Getter which will convert the complex raw data into something more display friendly:
valueGetter callback will be called for every row for
where we return the
country name and
results length respectively.
That might have seemed like a fair bit of work, but it's worth noting that we only had to import a single module and then reference the grid in a single component to get a grid up and running.
With the addition of a few simple properties we can enable filtering, sorting and so on. We can also start working providing the rest of the CRUD operations (creation, updates and deletions).
We'll take a look at all that and more in the next part of the series.
See you next time!
Lead Developer - Frameworks
Sean was the first person that Niall asked to join the team. Sean ensures that we can keep the agnostic in ag-Grid... he is responsible for integrating with all of our supported frameworks. He has also recently given a number of talks at conferences where his calm manner belies his years of experience.