Phonebook app in Angular
#
IntroductionIn this tutorial we are going to make a simple phonebook app with angular that uses Architect SDK
as a backend service. We will make a UI for our app and show how we can greatly simplify data management with Architect SDK
. For simplicity sake we won't use any external library. If you want to get started quickly check our Angular quick start guide.
#
SetupGo to folder of your choice and type following command:1
When asked to add routing type y
and press Enter
. When asked which stylesheet format would you like to use, select CSS option and press Enter
. Wait for a couple of seconds for everything to install. Open newly installed app in your editor of choice (I will use vscode) and serve the app by typing:
Check if the app is running on port 4200. If everything is okay you will see welcome angular page.
#
EnvironmentBefore we continue with building the UI we will setup environment. Go to environments folder inside src
, and add this line to both environment.ts and environment.prod.ts file:2
environment.ts file should now look like this:
environment.prod.ts should also have the same form, expect production prop should be true.
#
Adding componentsOur app will have three pages and one shared component: contact list for displaying and deleting contacts, contact form for adding and updating contacts, login page for user authorization and navbar for navigation. Lets create them. Type in the terminal:
Inside you app folder you should see four more folders contact-form
, contact-list
, navbar
and login
, and for each of those folders there should be 3 files: (actually 4 but we will ignore spec.ts files)
- .css file, where we will write our styles
- .html file, where we will write our markup
- .ts file where we will put our logic.
#
RoutingWe will now add routing. We need foempty-app
ur routes, root route /
, which will display login component, /contact-list
route will display contact list and /contact-form
route where we will display form for creating contacts and /contact-form/:id
for updating contacts. Later we will add route guars to prevent unauthorized users to visit /contact-form
and /contact-list
routes.
Let's go to app-routing.module.ts and them. First we need to import components we created. Add these lines below default imports and above routes constant.
Inside route array add four objects with following properties3:
Now go to app.component.html and after deleting everything inside it and put the following code:
If you check out app you should see
To check if other routes are working we can type appropriate paths in the url bar. To check if contact-list
is working add /contact-list
after the localhost:4200 part. You should see
Similarly for other routes.
Now that we added routing let's go and start adding styles and markup to our components.
#
Architect SDK serviceFirst we will install Architect SDK package.
- npm
- Yarn
We will now create Architect SDK service with the following command:
New file called architect-sdk.service should be inside src
folder. We will use Architect SDK via this service. Before we do that we need to configure Architect SDK. Inside src
folder create a new file called architectConfig.ts and put this code:
A lot of things happened here. First we imported architectSDK
and ArchitectResource
type from the package we installed. Then we imported environment
file to access baseUrl
we defined earlier. In order to have access to Architect SDK type system we defined Architect schema with property contact
whose type is Contact
. We will now should have full autocomplete in our editor (I am using VsCode).
We can add our new client
(which includes all functionality provided by Architect SDK) in various ways. We will do this through ArchitectSDKService
. First let's import client
from architectConfig.ts
in architect-sdk.service.ts
. Then let's add private field _architectSDK
and initializing it in the constructor.
We will define some methods that we will use later inside our components. After adding them ArchitectSDKService
should look like this:
Now we are ready to use Architect SDK
. Before we do that we should update our components.
#
Adding stylesWe want to share some styles across all components. Easiest way to accomplish such thing is with global styles. Put the following content inside src/styles.css.
#
NavbarWe will add navbar from which user can logout. In navbar.component.css
paste:
We want to redirect user to root route /
after logout. We will use ArchitectSDKService
for user authentication. Let's implement this. First import Router
and ArchitectSDKService
in navbar.component.ts
.
Then we should inject Router
and ArchitectSDKService
in our constructor.
Then let's add logout method.
First we will logout user and the navigate them to the root route (login
component).
Only thing that is left is markup. Inside navbar.component.html
paste this code:
We are done with navbar component. We will add it to contact-list
and contacts
component later.
#
Login componentLet's first start with login component. Insert into login.component.css
:
Next we want to collect user input. To do so we first need to import ReactiveFormsModule
in app.module.ts
file and put it inside imports array. app.module.ts
should now look like this:
Next in the login.component.ts file import FormBuilder and pass it to the constructor as a private variable. Inside constructor initialize loginForm field.
Also add login method that will, for now, just console.log
loginForm
value.
This is how login.component.ts file should look now:
Go to login/login.component.html and paste this code:
Here we have two input fields of type email and password, and a button of type submit. Notice that instead of name attribute we used formControlName, that form element has [formGroup]="loginForm"
, which bind loginForm
to the html form, and (ngSubmit)="login()"
which handle submit event with login method we defined earlier in login.component.tsx
. Now login page should look something like this . Type something in the email and password fields and you after clicking on Login
you should see result in the console.
Next we want to inject our ArchitectSDKService
into LoginComponent
. Import ArchitectSDKService
.
Now inject it by adding it to the constructor:
Now make login method async and pass login form value to architectSDKService
login
method.4.
Notice that we don't save login response. Architect SDK
saves this state internally. We can always check if user logged in by calling isAuthenticated
method. We will use this later to create route guards.
After successful login user should be redirected to contact list. Lets do that. Import Router
:
Now add it in the constructor:
Now let's redirect user:
login.component.ts
should look like this:
Now when you type your credentials5 you should be redirect to the /contact-list
route and you should see contact-list works!
.
Page is empty now so lets fill it up.
#
Contact list componentIn contact-list.component.css
we want to show all contacts, we want to edit contact, delete contact and create contact. Before we start add let's add some styles. Go to contact-list.component.css
then paste this code.
Inside contact-list.component.tsx
import Router
, ArchitectSDKService
, Contact
and pass them to constructor.
After fetching them we should store all our contacts in our component, so lets add field contacts
.
To fetch all contacts inside ngOnInit method put the following code:
Let's add a delete method that handles contact removal6.
First we send a request to delete contact by passing id
parameter to _architectSDKService
(this is handled internally by Architect SDK
) and, after request completes, we filter out that contact from contacts
array.
We also want to to edit and create users. That will be handled by contact-form.component.ts
. Add this code to enable redirects:
After all this changes contact-list.component.ts
should look like this.
Now in contact-list.component.html
add this code.
Here we iterate over contacts list and display each user information. We also added three event bindings for methods we defined earlier, addContact()
, editContact(contact.id)
where we pass contact id and deleteContact($event, contact.id)
, where we also pass $event
argument so that we prevent navigation when user clicks on delete button. By clicking on add contact or by clicking anywhere on contact item you should see contact-form works!
. By clicking delete that contact (after a while) should disappear. Contact
now looks like this (note if there are no contacts you should just see Contact list
with Add contact
button.) Try clicking on add contact, you should be redirected to contact-form
component.
Let's proceed to Contact form
.
#
Contact form componentFirst add this four imports in contact-form.component.ts
:
We sill use FormBuilder
ad FormControl
to build form, DomSanitizer
to sanitize user image url, ActivatedRoute
to get id param from url. We already used Router
and ArchitectSDKService
. Lets add them all to the constructor.
Add this fields above constructor:
title
will be title of the page, contactForm
is where we will store information user pass to the form, id
is where we will store contact id. We want to fetch contact data inside ngOnInit hook. Before we do that let's define getContact
method.
Now inside ngOnInit let's first get id
parameter, then based on the absence or that parameter define a title and fetch contact information.
We also want our users to upload and preview images so lets add method for handling that.
When user uploads image we create new object url and use that for our image src attribute. We also want to create or update contact. Since we use same form for updating and creating, we will decide what to do base on the value of id
parameter. If it is null (no parameter provided) we will create contact. If id
has some value we will edit contact. Also if the want's to use image we first need to upload that image, get url received as response and pass it to our form. Then we can update/create our contact.
Here is how we will handle this
After successful create/update we will redirect user to contact-list
. Now our file contact-form.component.ts
should look like this:
Now let's add styles and markup. Paste code below in contact-form.component.css
.
Now paste this into contact-form.component.html
.
You should see this on your screen .
Play around with form and see if everything is working. Try creating, updating and deleting contacts. There is only one thing left to do. Currently user can visit all pages contact-list
, contact
regardless if he is authenticated or not. We can fix that by using guards.
#
Route GuardRoute guard is used to prevent users from navigating to parts of application without authorization. Lets create one to prevent unauthorized users from accessing certain part of the app. First let's type following command in terminal:
Choose first option and a new file called auth.guard.ts
should be in your app
folder. Paste this code:
The most important part here is canActivate method. Using ArchitectSDKService
we first check if the user is logged in and if he isn't we we redirect him to /
route (Login page
). If user is logged in we return true signaling to angular router that user can access that route. Now all we need to do is to register guard to routes. Go to the app.routing.module.ts
, import AuthGuard
and add new prop canActivate
. After you done all that app.routing.module.ts
should look like this:
Now our routes should be protected. Try clicking on the logout. You should be redirected to login
page and you shouldn't be able to access /contact-list
, /contact-form
routes unless you login.
#
ConclusionWe showed how easy is to make a full app (though a simple one) using our powerful Architect SDK
that can easily be integrated into any angular application. To see full power of Architect SDK
check rest of the docs. You can find different ways to authenticate users, use webhooks etc. You can also check other tutorials we have.
- Make sure that you have globally installed Angular CLI. Go to https://angular.io/guide/setup-local for more information.↩
https://architect_demo.essentialz.cloud
is free appId that is available for demonstration purposes. When you are configuring your application make sure that you insert your app id instead ofarchitect_demo
part. It should like like thishttps://<your_app_id>.essentialz.cloud
↩- We could define different create contact component but a lot of code will be duplicated so we will use same component for both create and update contact. We will show later how to determine if the contact should be updated or created.↩
- If you like you can handle error inside catch block, by assigning it to some filed in the class and displaying error message to the user. However we will just console log message.↩
- If you don't have an account you can use
nikola@essentialz.io
for email andarchitectdemo2021
for password.↩ - We are prevent default actions because by clicking anywhere on the list item user will be navigated to
contact
component.↩