https://worldvectorlogo.com/logo/angular-icon-1

Basic Angular forms app with AWS Serverless Backend in Python — Part 1

Zakaria Soufiani
8 min readMay 2, 2017

Recently I had to learn Angular and as AWS Lambda and it was a bit of a learning curve for me as I wasn’t familiar with the framework and the AWS stack. I decided to write this guide to better my understanding of these technologies as well as help others.

This guide is focusing on the basics of creating a basic Angular app that is linked to a AWS DynamoDB database and uses AWS Serverless Python as a backend. We will first look into how we can create an app using the Angular CLI then connect the backend in a later stage in part 2.

A demo of the app available here.

Make sure you have installed the Angular CLI and able to create a development environment by following the guide on the Angular website, more information is available on the official Angular CLI Github.

Once you know how to start a project using the CLI we will create our app with the following command

ng new angular-learn-forms

and run the command

ng serve

to make sure our app is up and running on the default port http://localhost:4200/, you should be greeted with a similar screen saying

You can call your app whatever name you want but just make sure you keep consistency throughout your project.

The app will have 4 components:

  • AppComponent
  • NavbarComponent
  • HomeComponent
  • DatabaseComponent

The CLI command to create the app would have already created the scaffolding for our application as well as the AppComponent, now we only need to create the remaining 3 components by using the following commands.

ng g component navbar
ng g component home
ng g component database
ng g component forms

After creating these components we will mainly focus on the app directory where our components live, the tree structure should appear similar to this :

├── app.component.css
├── app.component.html
├── app.component.spec.ts
├── app.component.ts
├── app.module.ts
├── app.routing.ts
├── database
│ ├── database.component.css
│ ├── database.component.html
│ ├── database.component.spec.ts
│ └── database.component.ts
├── forms
│ ├── forms.component.css
│ ├── forms.component.html
│ ├── forms.component.spec.ts
│ └── forms.component.ts
├── home
│ ├── home.component.css
│ ├── home.component.html
│ ├── home.component.spec.ts
│ └── home.component.ts
└── navbar
├── navbar.component.css
├── navbar.component.html
├── navbar.component.spec.ts
└── navbar.component.ts

At this point we will need to check that the imports and declarations in our app.module.ts have been updated with the components that were just created. Typescript normally does a good job at this but we will check for good measure and it should look like this.

Now we can start modifying the files created, starting with the navbar.component.html we will populate it with the following HTML code.

This is a basic HTML navbar that will be fixed at the top of the screen and this can be achieved by adding the tag <app-navbar> to the app.component.html file.

Since you are running “ng serve” the app should automatically load and you will be able to see the navbar that you just created but it looks rather plain as it is just HTML with no CSS styling. An easy way to add styling to your webapp is by using a Boostrap library, we will use Bootswatch by adding a <link> tag to your your index.html file like so

<link rel="stylesheet" href="https://bootswatch.com/3/flatly/bootstrap.css" media="screen">

Now your app should start taking form, you will notice that the links are highlighted and can be clicked but they are not active, this is where we need to link our components together and this can be done with routing.

You will need to create a file app.routing.ts in the app folder and populate it with the following.

  • First we need to import the following dependencies: ModuleWithProviders, Routes and RouterModule, then the components we created earlier: HomeComponent and Database component, there is no need to import the NavbarComponent as it doesn’t route anywhere and it is fixed to the top of the page.
  • Then we structure the paths with their respective components.
  • Finally we add the routing import to the app.module.ts file which will look like this now:

Now we will add a <router-outlet> to the app.component.html file to be able to display the contents of the components we just routed, the <router-outlet> is wrapped in a “container” to make sure the contents get display correctly under the navabar.

Finally, we add the paths that we created to the navbar by modifying the navbar.component.html by adding the routerLink directive to the links on the navbar.

The components are fully linked now and we are able to navigate between the different paths using the navbar, the container displays the respective HTML file for every component.

Next, we will populate the forms.component.html with the following to create a basic form to gather information that we will later synchronize to a database.

Here’s a demonstration of what you should be able to achieve.

Web App demo in browser

Now for the sererless lambda part

Here is the plan:

  • Set up an account with AWS, create a basic service with the Serverless Framework using the Python template and deploy it.
  • Write the functions needed to run our app and deploy the API.
  • Create services in Angular and update the components to add HTTP requests to our new API.
  • Done !

Set up AWS and the Serverless Framework:

Creating a new Amazon Web Services account is quite easy and straight forward just follow the steps in the documentation. And since we are not doing any heavy cloud computing, you will fall well within the free tier which gives you 1 million free Lambda requests per month.

Make sure you have Python 2.7 installed on your machine then go ahead and install Serverless with the following command

npm install -g serverless

Next you need to set up your provider credentials by following the steps here.

Now you are ready to create a new service and deploy it using the following commands

$ sls create --template aws-python --path inputform-backend
$ cd inputform-backend
$ sls deploy

Once you create the boilerplate you should see on the terminal window the version of the framework you’re using, v1.10.1 in this case

Terminal boilerplate

Deploying should take a minute or two and once the process is done, you should see the name of the service and the functions deployed. The boilerplate hello function was deployed in this case

Terminal deploy

The lambda function should be live on your AWS console as well.

Now we need to create the lambda functions starting by creating 4 Python files and update the serverless.yml file. We can go ahead and delete the handler that got created for the hello function as we won’t need it.

First up is the create.py file, this is the function that will load data into our DynamoDB. As you can see, we are accounting for all the data that will be passed from the forms: firstName, lastName, email, comments and options.

The second python script will scan the database and returns a list of all the profiles available in the database using a http get method.

The third script is pretty similar to the previous one but in this one we will query the database using the id key to retrieve only one profile rather than the whole list.

This final script is just a workaround for a bug in Python where the JSON encoder is unable to handle decimal numbers.

Finally we need to update the serverless.yml file by adding the functions with their corresponding methods and paths as well as the resources for the DynamoDB tables. Make sure that the service name is the same as the one used to deploy it.

The backend is now done and the directory should look similar to this.

├── create.py
├── decimalencoder.py
├── get.py
├── handler.py
├── list.py
└── serverless.yml

Now deploy the functions by running

sls deploy

This time when the deployment is done, we will end up with actual endpoints for our API and the corresponding methods.

We can test that the functions are correctly running by testing them in the terminal with an example. Make sure you use the proper URL that you get from deploying the service.

curl -X POST https://vwabl3g6ig.execute-api.us-east-1.amazonaws.com/dev/form --data '{"firstName":"Dipper", "lastName": "Pines", "email":"dipper@gmail.com", "comments":"Gravity Falls is weird", "options":"Tabs"}'

If the call is successful you should see a JSON dump on the terminal with the information that just got entered with its id and time stamp. You can also see the item added on the AWS console for DynamoDB.

Add services and update the HTML form

First we need to create the service that will handle the HTTP requests.

Create a directory called services inside the app folder and inside that folder create a file called database.services.ts. This service will have two main usage cases: listing the entries available in the database and creating new entries. The API_URL will be the same as the one you created from deploying the lambdas previously.

After the service is set up we need to call these methods in the forms.component.ts. After injecting the DatabaseService in our constructor and added it to the providers, we can access the methods created and pass the input gathered from the form.

Now we need to update the forms.component.html to bind the information gathered as well as validate it.

The database.component.ts is responsible for scanning the database using the database service and calling the getInfo method then storing the objects in an array.

Finally the database.component.html will display the items on the database by looping over the list using *ngFor. The data will be displayed in a table.

At this point, you should have a working app that takes input from the user, stores it in DynamoDB and displays it in a table.

Some improvements that can be made:

  • Add an API Key
  • Add a delete option on the table
  • Make use of the form/{id} to display user specific information
  • Display the profile in a different form — cards maybe ?
  • Unit tests, unit tests, unit tests and unit tests.

The Github repo can be accessed here:

A demo of the app available here.

Please keep in mind that I am not an expert and decided to write this guide to help me better my understanding of this stack and hopefully help others as well. Feel free to ask me any questions and I will answer them to the best of my ability and if you see any improvement that can be made please share them.

If you found this guide helpful tweet me @zaksoufiani and Thank you !

--

--

Zakaria Soufiani

This is my attempt to share some of the knowledge I gained and hopefully help others.