Tuesday, December 18, 2018

Part 13 - Building your Mobile App Signup Page

We have made it to an important stage in your mobile app development progress.  At this point we will be able to exercise a repeatable process to build out various features of your mobile app.  Open Visual Studio Code to the Invoicing project we have been building and let's get to it!

Design

First let's visit draw.io and mock up your new page.  Here is what I have come up with.

Create Account

Create Component

Create the new Signup component (page).

image

Import the new component into the App module

/src/app/app.module.ts
image

Add Page Navigations

Add navigation to this page from the Login (Home) page such that we can work on the design of this page.

/src/pages/home/home.html
image

/src/pages/home/home.ts
image

Design

Add HTML and other components to the signup page to match our design.  Refer to the Ionic documentation for built in components.

/src/pages/signup/signup.html
image

Check and edit your design by running 'ionic serve' and navigating to the page.  Each time you save, the application should restart and you should be able to see any edits made.

image

image  image

ViewModel

Create a ViewModel with a property that maps to each of your input fields and link the ViewModel to the user interface by adding ngModel to each of your inputs.

/src/view-models/SignupViewModel.ts
image

/src/pages/signup/signup.ts
image

/src/pages/signup/signup.html
image

Connect to Server Side Controller

First we have to update the button to run a method in the signup.ts file.

/src/pages/signup/signup.html
image

Inject the AuthProvider into the Signup component such that we can use this service to connect to the server.  We created the AuthProvider in a previous post.

/src/pages/signup/signup.ts
image

Post the ViewModel to the server's Account Controller in a Signup endpoint that we'll create.

/src/pages/signup/signup.ts
image

Not too bad so far… It looks like we have made it through the majority of the Mobile App side of the changes, but as mentioned above we have assumed we have an AccountController with a Signup method/endpoint.  We also need the SignupViewModel copied to the server side project.  We didn't create either of these yet, so we'll do that next.  Open up Visual Studio 2017 to the Invoicing solution.

Server Side ViewModel

Add SignupViewModel.cs to the Invoicing.Core project in the ViewModels folder.

image

Server Side Controller

Add a Signup method similar to our previously created Login method.  We'll piggyback off of the existing login method to log the user in after the signup process completes successfully.

AccountController.cs
image

Next, we need to add code to actually complete the signup.  We'll add this to the existing AccountService since it is still related to the users' accounts.  If this was unrelated to account services, you would create a new service next (though, consider if it should be in a different controller at that point).

Server Side Service

Using the intellisense to add the Signup method is the easiest way to add the method stub to the corresponding service's interface.  I prefer to use the class representation rather than the primitive representation for variables.  It just looks cleaner to me, so I have made those edits as well.

IAccountService.cs
image

Then implement the missing interface method.

AccountService.cs (initial implementation of interface)
image

At this point, we need to create an ApplicationUser.  We would like our repository to handle the database manipulation, so we'll again pass the signupData down the line to the repository through the UnitOfWork we had previously added to the AccountService.  I also updated ‘bool’ to Boolean.

image

Use intellisense to add the AddUser method to the repository.

It may seem like we keep needlessly passing the this data along, but as we implement more controls over this process you will see the reason we are doing this.  An example of something we may add here would be checking if the user already exists in the system.  If we don't add this check, we'll end up with duplicates in our database!

Repository

Add the new user by first creating a new ApplicationUser, setting all of the fields, and then adding it to the _context field that we had added in the Repository base class.  It looks like our Model doesn't yet have Name, CompanyName, Address, or Phone.  So naturally, let's add those next.

image

Model

I’ll use the repository to quickly add these and then change the type representation quick then make my additional edits.

image

I updated the class representation to "String" for each of them, removed "internal" from the "set" property shortcut, and added a StringLength annotation to each of the fields.

image

Update Database

Now that we have made changes to our database models, we need to have these published to the database.  To do this, we need to add a new migration, then update the database.  We did this in a previous post through the Package Manager Console.

Note: Be sure to change your "Default project" to the project containing your entities, in this case it is the Invoicing.Core project.
image

Let's use DB Browser for SQLite to see if these made it to the database …and it looks like they made it!

image

Wrap-up by updating the Login service

Now that we have built out the Signup process, we need to fix up our Login process.  If you remember from Part 12, we tested a specific email and password.  Now that we have a Signup process, we can test the login vs. what is stored in the database.

AccountService.cs
image

The only method we had available to retrieve an ApplicationUser was a Get(int) method we had added to the base class.  Since we don't have the Id of this record, we need to add a new method to retrieve the user record by email.

ApplicationUserRepository.cs
image

As you may be able to see at this point, everything has it's place and adding a new feature is more of a process rather than an invention each time.  We can use intellisense to help us along the way and drill down from the user interface all the way down to the model and back.  Now, if we have done everything correctly we should be able to run this and have a successful signup and login.
Press the Play button on the Visual Studio 2017 solution and run ‘ionic serve’ in Visual Studio Code.  Ensure you open the developer tools to ensure we don’t receive unexpected errors along the way.

image    image

And somewhat surprisingly, I got it on the first go.  Let's check the database again to see if we have an actual ApplicationUser record and then re-test our Login page with a valid login and an invalid login just to be sure.

image

Testing with an invalid login provided me the Console.Log() of Invalid Login we had created in a prior post.  Changing the password to the correct password allowed me to proceed.

As you can see, my password is currently in plain text, which is a huge NO-NO.  In the next couple posts, we'll work on security.  We'll be encrypting the password, providing a token to the mobile application, and locking down our queries to only properly authenticated users.

Wednesday, December 12, 2018

Publishing your Visual Studio Projects to GitHub

I want to take a quick intermission to publish our project on GitHub since we put so much work into it.  Even if you decide not to publish your project to a public repository, it is important to add your project to some kind of source control.  Remember to commit your changes frequently with clear descriptions in the event you need to quickly roll back any changes that may break your application.  For this post, we will install and use the Visual Studio GitHub plugin to publish to a public repository.

Download the GitHub Extension for Visual Studio here: https://visualstudio.github.com/index.html

image

While this installs, you can create a GitHub account at https://github.com/

Open Visual Studio 2017 to the Invoicing solution.  Right click on the Invoicing solution and select Add Solution to Source Control…

image

Next click the Team menu option and select Manage Connections…

image

From the Team Explorer pane that pops up, click Sign in under the GitHub connections.

image

Sign in to your GitHub account.

image

Next, click the drop down where it says "Connect | Invoicing" and select the Sync option.

image

The Team Explorer pane should show GitHub as an option.  Select Publish to GitHub.

image

Next, fill in the details of the GitHub account you created and name the app.  I named this one InvoicingApp.  Then click Publish.

image

Now your code is published on GitHub.  Since we setup the mobile app portion inside this project folder, that project will automatically be pushed and synchronized to GitHub as well.

image

You can now see the published app in your GitHub account.

image

You can also clone this repository to obtain the code I have just published including future posts.  I will commit changes after each post.

InvoicingApp Repo: https://github.com/MECCSoftLLC/InvoicingApp

Saturday, December 8, 2018

Part 12 - Connecting to the Server from the Mobile App

We must now complete a little more setup on the mobile app side in order to make requests to the server from the mobile application.  This will involve setting up some global environment variables, creating a new service to handle sending and receiving requests as well as building the data model that will be received from the server after a request is made.  To keep things easy to test, we will also need to allow Cross-Origin Resource Sharing (Cors) to allow the local web app to connect to the local server app.  This won’t be an issue when we publish this to a single virtual machine on AWS, so we'll only enable this for our testing.

Start by opening up Visual Studio 2017 to the Invoicing solution.  Right-click on the Invoicing.API project and select Properties.

image

When the properties window opens select the Debug tab on the left hand side.

image

Then click Copy after the Web address by the Enable SSL checkbox.  In my case I get the following on my clipboard: https://localhost:44369/

image

Next open up Visual Studio Code to the invoicing project.  We need to create an environment.js file to save some environment variables that we’ll use in our project.  This is where we will put the web address we just copied.  Right-click on the src folder and add a new file called environment.js.

image

Next we will add a couple variables.  The first will be a 'production' variable that we will set to false for now and a 'url' variable that we will set to the web address we copied above with 'api/' added on the end.

image

Next we should setup a service to handle making the connection to the database such that we don’t have to set this up in each of our pages and to keep server communication consistent.  To add this service, open the terminal window using CTRL+Shift+~ if it isn't already open and type ionic g provider Auth

image

This creates a new Angular Service called Auth.

Note: They are referenced as Providers in Ionic, but they are the same as an Angular Service.

You should now see a new providers folder, auth sub folder and an auth.ts file.

image

Open that file and add the environment variable as an import to the top and ensure the HttpClient is included in the constructor.

image

Notice that HttpClient is new and it happens to be in a module that we haven’t used before.  Therefore, we also need to import the corresponding module into src/app/app.module.ts to ensure it is included in our app when it is built.  Otherwise when the AuthProvider is started, it will produce an error indicating it can’t find HttpClient.

image

Let's now create our RequestResult model on the client side to match the one we had created had created on the server side.  This will be the response format from the server and will be needed for the methods in the AuthProvider class.

Right-click on the auth folder and add a new file called RequestResult.ts.  Add the same properties that we added to the server side RequestResult.cs class in the server side project.

image

Next we will add methods for the standard Get, Post, Put, and Delete http request methods to the AuthProvider class along with an error handler method.

image

These will be used to communicate with the server pre-login, we will have to come back and add to this after we finish up the login process to handle a login token which will ensure we maintain a stateless cloud environment.

One last step is needed to allow our testing environment to connect to the API.  Open Visual Studio 2017 and open the Startup.cs class in the Invoicing.API project.  In the ConfigureServices method, we need to add Cors to the services used in the application.  This will allow us to make API calls from our test web app to the server side API web app and avoid security restrictions.

image

And then in the Configure method, we will allow access from any source only when in development mode.

image

That should be all we need to get started.  Start the server side project by clicking the play button in the toolbar.  A browser window will open and you will receive a ‘page not found’ message.  This is OK and we can address this later.  Leave this page open while proceeding onto the next step.  It is important that this project is left running to accept requests from our mobile app.

image

Now, let's create our first call to the server and see if we can get a response.

Go back to Visual Studio Code and open up the login page’s ts file for the application in src/pages/home/home.ts and add the AuthProvider service in the constructor.

image

Next, add to the login method to call the server's Login method on the Account controller and pass in the loginData that we have bound to the controls on the Home page.  When the response comes back, if the State was set to 1 by the server we should proceed to the InvoiceListPage, otherwise we should log an error and not proceed.

image

Let's run the app by opening the terminal (CTRL+Shift+~) and type ionic serve

image

First enter invalid login credentials and ensure the error of Invalid Login was logged in the developer tools (press F12 in your browser and click the console tab for the developer tools).

image

image

And then try again with the credentials that we had specified in our AccountService.cs file to ensure those work.

image

And we're in!

image

We have successfully logged into our mobile application by making a call to the server app via an API.  Next we’ll go through the process of adding an entirely new page, the signup page.  By adding the Signup page we will touch just about every part of our application and really get a feel for developing in this stack.  After that we will quickly follow-up with password encryption and passing an authentication token between the app and server to ensure we only provide data to authenticated users.