In this tutorial we’re going to build a simple single-page application with Angular 2. This is intended for developers unfamiliar with 2 or having some experience with AngularJS 1. First of all, I got Visual Studio Code installed on my machine and it’s running on Linux. I chose VS Code because we’ll be working with TypeScript mostly and it has great support for it, but you can code in your favourite IDE as well. Next, I’ve decided to save some time and clone the excellent Angular 2 starter kit by Minko Gechev called ‘angular-seed’. For that you’ll also need Git, Node.js and npm.
- Get Visual Studio Code
- Get Git
- Get Node.js with npm
- Clone ‘angular-seed’
- Open the project in the VS Code editor
Next - the backend. Here, I could write a simple backend in Node.js and Express but I’m lazy so I chose not to. Instead, I’m going to use Para for my backend and I’m not going to write any code on the server. If you are new to Para, it’s a general-purpose backend framework/server written in Java. It will save me a lot of time and effort because it has a nice JSON API for our app to connect to. To run the server you’re going to need a Java runtime.
Now, check if Para is running - open your browser and go to
http://localhost:8080/v1. You should see a response like
We haven’t got access keys to the server yet, so let’s go ahead and do that, open:
Save the credentials to a file, we’ll need them later to access the backend API.
Let’s create an app for storing recipes - a recipe manager. Our goal will be to build just the basic CRUD functionality,
without adding extra features like authentication and login pages. By default the backend is secured and only signed
requests are allowed, but for the purpose of this tutorial we’re going to add a new permission to allow all requests to
just one specific resource -
Go to console.paraio.org and enter the credentials that you saved in the beginning. Also
click the cog icon to edit the API endpoint and set it to
http://localhost:8080. Click ‘Connect’.
Next, go to ‘App’ on the left and edit the root app called
para. You’ll see a section for resource permissions and
there you will write a simple permission definition in JSON:
This defines a single permission that allows
* - everyone to access
/v1/recipes using a list of allowed methods,
in this case
* - all HTTP methods and
? - anonymous access is allowed. Thus, we’re essentially making this resource
publicly available. Click ‘Save Changes’.
Now let’s go back to our frontend and edit the ‘Home’ component under
src/client/app/+home. We want to edit the HTML
code a little bit in
I’ve added the “Add” button which shows the form where we can write a recipe (controlled by
showForm), a textarea,
and a close button. Notice how the text value of the “Add” button changes to “Save” when we’re in edit mode. Coming
from Angular 1, you’ll notice the weird
[(ngModel)] syntax - it’s a two-way binding (single brackets is one-way).
*ngIf is just shorthand for
Also, I chose to set a new title in the header section in
Let’s edit the
NameListService which is part of the starter project and rename it to
RecipesService. You’ll have
to rename all occurrences of the class and also rename the folder
src/client/app/shared/name-list. In the code for
home.component.ts we’ll add a new field
newRecipe: string to hold the recipe text and the whole this should
look like this:
Now we’re going to focus on that
addName() method. First rename it to
addRecipe() and include the new field when the
service is called:
Let’s also add the method for listing recipes
listRecipes() and call it upon initialization:
Now we have to modify the
RecipeService class to allow for another parameter
text. Let’s also add the code
for making the
POST request to the backend:
Going back to the component code in
home.component.ts, we have to subscribe to the
Observable returned by
recipeService.add() and get back the list of recipes when they arrive.
Finally, we’ll add to
home.component.html the markup for listing all available recipes, and also a box which appears
when there are no recipes to show:
There are two click events here - one for editing and one for deleting recipes. Let’s add the styling for
.empty-box later in
main.css I’ve also added a few more tweaks to the CSS:
So, we should now we able to add recipes and after we click “Add” the form should be cleared and closed.
For this let’s add the following code in
home.component.ts to reset the state of the form:
recipeId will keep the value of the
id when a recipe is being edited. When “Save” is clicked this
id is passed to the service and the backend so it won’t create a new object, just update an existing one.
Let’s add more methods in our
recipeService for updating and deleting recipes.
Nothing special here, except the
.toPromise() in the end which converts an
Promise and executes
it right away. We’re issuing these requests and we don’t care about the results because we can update the UI
instantly, without having to wait for the request to finish.
home.component.ts we’ll modify the code for
addRecipe() to also edit a recipe when
recipeId is set.
removeRecipe() are relatively straightforward - when editing, we set the mode in
editMode = true and we show the form, when removing we just filter the array
recipesList and we discard the
deleted recipe if it matches the
So far, so good. We can now add, edit and remove recipes but they aren’t very pretty and the formatting of the text is lost. In the next step we’ll make it possible to write the recipe text in Markdown and then render it in HTML.
First of all, let’s install
Then we import it in
import * as marked from 'marked';. Finally we’ll add a simple method
md2html() which will be used in our template.
In our HTML template we change the line
<div></div> like this:
Now we render the text to HTML on the client and this allows us to write beautiful recipes like this:
Final touch - recipe search. We’ll use the built-in full-text search in Para. In
Finally, we add the search box in the template below the heading:
And we’re done! The final result of our Recipe Manager 1.0.0 (check out the live demo):
Learning Angular 2 takes some time as it introduces a lot of architectural changes and new syntax.
Writing in TypeScript feels fresh and more like writing in a real statically typed language like C# or Java,
rather than a dynamic language like JS. The
import syntax was a bit hard for me to get used to, especially
with all the different files I had to navigate through. In general, the experience of writing Angular 2 apps is
great - the syntax is clean, the app is well structured and the error messages are clear and understandable.
Things we did:
- wrote a few fancy AJAX calls to our backend API using observables
- wired a bunch of simple TypeScript code between a component and a service
- wrote some good old HTML and CSS
- imported an external library with npm an typings
Things we didn’t do:
- write any backend code
- define the “recipe” data type on the server or in a database
Have questions or suggestions? Chat with us on Gitter!