Dev Diary S01E08: Fleshing out the Angular and Azure Web API components


 

Introduction

In the last post we talked about me deleting the Azure Application by mistake! In this post we will flesh out our Azure Web API so that we can start to add, edit and store our Invoices in the API layer. We are not quite ready to start implementing the Azure Document Db side yet, that will be in the nexr post.

Let’s get started!

 

Implement the Invoice API

So I am going to implement the Invoice API using a new Web API Controller, the InvoiceController .

In this initial version, the InvoiceController has implementations for getting all the invoices, get a particular invoice with its reference and add a new invoice and update an existing one.

The guts of the InvoiceController works with an Invoice Repository which has been implemented with the Repository pattern. .

Finally, we need our plain-old CLR objects (POCO), which will represent our Invoices.

 

Invoice Controller

So firstly, I created an InvoiceController in the Controllers folder using the WebAPI item template.

The code for the InvoiceController.cs is shown below:

 

Invoice Repository

Next, I created the InvoiceRepository class in a Repositories folder. The repository has been implemented so that it returns a list of Invoice objects.

The InvoiceRepository.cs implementation is shown next:

 

Invoice Entities and the Special Case Pattern

The Invoice entity is implemented as a new class held within the Models/Entities folder. The Invoice Poco class has all the fields which are used to hold the information related to the Invoice.

The code for the invoice.cs is shown below:

 

The special case pattern is a approach that I use in most of my applications. The objects have an Exists field which can be used to check whether the object has been found.

This approach helps to avoid using nulls which can be ambiguous when returning data from a particular method. I implemented the InvoiceNotFound  class special case.

 

Json camelCase formatting

One of the things that we need to do is make sure that the WebAPI formats the JSON in the right way. For JavaScript the right format for an objects properties in JSON is camelCase, where the first letter of the object’s property name is lower case and each subsequent word starts with an upper case.

For example:-

CustomerRelationshipNumber becomes customerRelationshipNumber

So how do we set this up with Web API? Well we needed to do a little tweak to the WebAPIConfig.cs file. This is how it looks:

The code sets up the Json Serialisation so that it uses a CamelCaseFormatter to resolve the property names on objects. This is applied globally.

 

 

Update the Angular Application to call the Invoice API

Now that the Invoice Controller is implemented in the WebAPI, next I started on the Angular client so that it calls into the API.

 

invoiceDataService.js – calls into the API directly, the code is shown below:

The invoiceDataService calls into a shared function executeSave() which will serialize the data being passed into it. Depending on the type of operation on the data, add/update etc then a different method is used.

POST – used to add a new object to the data through the API

PUT – used to update an existing object through the API

 

InvoiceControllers.js – implements the list invoices and add invoice controllers which call into the invoiceDataService. The code is shown below:

 

app.js – changed to add the modules for these new files

Also we added new routes for the add, edit, view invoices.

 

Update the List Invoice View to allow editing of the Invoice

So now we have the ability to view a list invoices from the GetAll() function of the InvoiceController.

We should allow a user to view and edit an invoice. This is implemented by the following changes.

list-invoices.html – the code is shown below:

The list-invoices.html now has an event to respond to an onclick event. This passes through the current invoice.reference of the record so that we are editing the right Invoice.

This calls into the updated controller, which exposes the function showInvoice()  on the $scope object. The function uses the $location service to change the Angular view to #/invoice/{reference]/view which will in turn direct the user to the view-invoice.html page.

We will discuss that bit of the solution next.

 

Another view was created called invoice-display.html, this is the code:

The code above represents the display invoice view, a bit of a mouthful I know. To be honest I am not sure why I did it this way but hey ho. I mean, there is no need for a view for new, edit and view Invoice. I will come back and refactor this in a later episode.

This view has got an edit button, which will allow us to transition and edit the invoice. This calls into the viewInvoiceController.editInvoice() function.

 

 

Another view was created for edit-invoice.html  this is the code:

The code above represents the edit invoice view. This allows a user to make changes to the invoice and then save those changes back by calling into the Invoice Controller REST API.

The code is structured in a similar way to that of the edit Invoice and add Invoice.

On a successful save then the user is returned back to the list of invoices.

 

Problems

The following problems were experienced whilst building out this portion of the application.

Error when viewing the invoice due to issue with routing

Error: {“message”:”The request is invalid.”,”messageDetail”:”The parameters dictionary contains a null entry for parameter ‘id’ of non-nullable type ‘System.Int32’ for method ‘Itsp365.InvoiceFormApp.Api.Models.Entities.InvoiceForm Get(Int32)’ in ‘Itsp365.InvoiceFormApp.Api.Controllers.InvoiceController’.

The cause of this was my WebApiConfig.cs. Which setup a route:

config.Routes.MapHttpRoute(
name: “DefaultApi”,
routeTemplate: “api/{controller}/{id}”,
defaults: new { id= RouteParameter.Optional }
);

Unfortunately, this did not resolve to the function

InvoiceController.Get(string reference);

bur rather the function

InvoiceController.Get(int id);

The following change was made to fix the routing:

config.Routes.MapHttpRoute(
name: “DefaultApi”,
routeTemplate: “api/{controller}/{reference}”,
defaults: new { reference= RouteParameter.Optional }
);

 

Method HTTP Status Code 405: Method not allowed

This error message was thrown when I added the edit Invoice feature. The edit invoice feature when it saves, calls into the API using an HTTP PUT method. The call fails with a message saying that the Method is not allowed.

In turns out that this issue was very similar to the routing error just mentioned.

The default route was changed to:

config.Routes.MapHttpRoute(
name: “DefaultApi”,
routeTemplate: “api/{controller}/{reference}”,
defaults: new { reference= RouteParameter.Optional }
);

Therefore, the routing was expecting to the PUT method to have method signature such as:

[HttpPut]

Update(string reference, [FromBody] invoice)

but we had:

[HttpPut]

Update(string id, [FromBody] invoice)

Making the change to the function to correct the name of the first parameter from id to reference resolved the issue and the save button worked correctly.

Conclusion

This episode we added support to add/edit and update our Invoices through the MVC Web API. This involved additions to both the server side WebAPI and the Angular client side.

We had a few problems which have been explained.

 

Here are the screenshots showing the changes in action:

image

image

 

Github

The repository for the Invoice Form App Client can be found here:

https://github.com/ithinksharepoint/IT365.InvoiceFormApp.Client/tree/7034429583821c0208c6956ee561c5a9f740a1fe

 

The repository for the Invoice Form App API can be found here:

https://github.com/ithinksharepoint/Invoicing-Application/tree/13f1a71d146cd8afba20d89991324cbcd17272c1

 

Next Episode

In the next episode we will start to actually do some Azure Document DB. The WebAPI will be modified and we will implement the calls into Azure Document Db.

Thanks for reading, I hope you can join us for the next session!

Dev Diary S01E06: Azure MVC Web API, Angular and Adal.JS and 401s


Introduction

In my previous post, we discussed how to implement Adal.JS into your Angular application. This allows us to use Azure Active Directory as our authentication mechanism.

In this post I am going to go through and create the MVC Web API which we will then start to call from our Angular client to manipulate the Invoices.

 

Creating the MVC Web API Project

Right then, so first of all we need to create an MVC Web API Project. There are lots of guides out there such as this one on the ASP.NET site.

Anyway, I fired up Visual Studio 2015.

  • File->New Project
  • Chose the Visual C# ASP.NET Web Application template
  • Created an MVC 4.5.2 template Web Application

image

  • Selected the folders and core reference for MVC and Web API
  • Selected to “Host in the cloud”
  • Then clicked Change Authentication
    • Clicked on Word and School Accounts
    • Choose Single organisation and selected my domain ithinksharepoint.com
    • Also selected Read Directory data option

image

  • Now click Ok
  • Clicked Ok to start creating the project

Next, you are presented with a screen to start configuring your App Service.

So I setup an appropriate name for the Web App

  • appropriate Web App Name
  • Choose my subscription
  • Chose Resource Group
  • Chose App Service Plan
  • Clicked Create

Visual Studio then worked its magic and created the Project with all the Azure services behind the scenes.

Then it setup the Organizational Account and App Insights. Once this was all completed we have a working Azure Web Application and are ready to start adding the Web API components.

 

Configuring Azure AD Authentication for the WebAPI Application

To be honest I was a bit surprised that I had to do this next step but when I was trying to find the application in Azure AD, I could not find anything. Also I could not find anything in the project either related to Azure AD.

So to configure Azure AD Authentication for the WebAPI application I had to do the following:

  • Right-click on the project
  • Choose “Configure Azure AD Authentication”

This fires up the Azure AD Authentication wizard

  • Click Next
  • Under Single-Sign-On
    • Choose your domain
    • Provide an appropriate App ID Uri.
    • Choose create a new Azure AD Application
    • Click Next
  • Under Directory Access Permission
    • Select Read Directory Access is not already enabled
    • Click Finish

This will start a wizard which will set everything up. The end result is visible in https://manage.windowsazure.com

 

 

Adding the WebAPI Components

We have a .NET MVC WebAPI project with very little in it.

Let me explain what I did next, so I would like to have two services for the first phase.

  • Configuration Controller – used to get the system and user configuration for the application.
  • Invoice Controller – used to add, edit, remove and list the invoices found in the application.

What we will do is create the Configuration service with a simple stub, firstly with no authentication so that we make sure it works and then we will make changes to the WebAPI layer so that it requires authentication.

 

I created the Configuration Controller. This was achieved by the followingNyah-Nyah

  • Browsed to the Controllers folder
  • right-clicked Add->Web->Web API->Web API 2.1
    • ConfigurationController.cs
  • Modified the initial code so that it looked like this

 

Next, we need to deploy this code to Azure and try it out.

I published the project to Azure by doing the following:

  • Right-click on the project –> Publish

image

  • Next choose Publish from the wizard

This will start the publishing process and push the code up into Azure.
Oh dear, this did not go so well and I received the following screen:

image

I ended up having to switch on customErrors as recommended by the error message. It turned out that there was a reference to the System.Spacial.dll. The project did not need this and removed it from the project references. The site was published and then ended up with the following screen.

image

I accepted the request for permissions and then was redirected to http://localhost which failed to work as I was not debugging the application.

Third time lucky, this time I ran the project using F5 and it all worked nicely, redirecting to http://localhost.

Just in case you do not believe me, I took the screenshot below:

image

 

We can also see that our API is working by browsing to https://localhost:44356/api/configuration and we receive a block of Xml as shown below.

image

Ok, now that we have the service up in the cloud, lets update Angular to consume it.

 

Update Angular client application to consume WebApi

So I thought I would update the Angular application, add a new page for settings. Firstly, the page would just load in the configuration but eventually this page will allow users to setup and configure the settings for the application.

In order to be able to consume the configuration api endpoint, I needed to do a couple of things to the application.

  • create a new view called settings.html
  • create a new service called configurationService.js
  • create a new controller called settingsController.js
  • configure the app.js to load these new modules
  • configure the index.html to load the scripts

So lets go through each of the components, starting with the settings.html page

 

Next, we have the settingsController.js

 

Lastly, we have the configurationService

 

We have the guts of the changes required, of course we need to link these pages into the application.

So the app.js needs to be updated with the new route for the settings page. Also we need to setup the configurationService.

 

Also the index.html needed to be updated so that we have a link for the settings page.

 

Phew, that is quite a big change, so lets go and try this out.

image

I browse to the application and click on the settings button.

 

Unfortunately, I get an error and looking into the browser developer tools we see the following message:

XMLHttpRequest cannot load https://itsp365invoiceformappapitest.azurewebsites.net/configuration. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 404.

 

Cross-Origin Resource Sharing (CORS) issues

So, what is going on?

Well we haven’t allowed the API to be able to process requests from domains that isn’t its own. The way we do that is through CORS configuration within the WebAPI.

To get this to work we need to configure the WebAPI by

  • Installing the Microsoft.AspNet.WebApi.Cors NuGet Package (current v5.2.3)
    • Not the Microsoft.AspNet.Cors NuGet Package (this does not give you the assembly System.Web.Http.Cors).
  • Modify /App_Start/WebApiConfig.cs

Now,its able to call in and get the configuration settings correctly!

image

 

Switching on Adal.js

We have proven that we can talk to our MVC Web API endpoint. So that is good news but now I had to get it to authenticate through Azure AD, get a access token and use that when making requests to the API.

Fortunately, Adal.js comes to the rescue here and a lot of the heavy lifting is done for you!

So let’s have a look at this. This bit did take me a while and I will explain why a little later. Though the following people and posts really helped me get to understand how Adal.js handles authentication when  authenticating against different endpoints.

First, we need to tell Adal.Js about the endpoints that will require authentication and we need to provide a way to map those endpoint URLs to resource name.

So to do that we configure the endPoints object when setting initialising the Adal library. Currently this is being setup by the following code snippet in app.js :-

 

 

The important part of this is the endPoint array object. This is an array of objects where you have the URL associated to the application Id Uri.

If you remember that is this section of the application configuration in Azure Ad.

 

Once we have that value we need to associate the APi Url to the App Uri Id.

This allows Adal.JS to provide the right resource id when requesting an auth token.

 

Turn on Authentication in our Web API layer

So now we have Angular configured to authenticate against Web API with Adal.js. We just need to switch on authentication for the Web API layer.

This is pretty straightforward and requires the addition of the [Authorize] attribute to our Web API Class or Methods. The change is shown below:

 

A recompile of code and Publish now allows us to test the changes out.

 

HTTP 401s and Debugging Azure WebApps

So I thought I had everything setup to allow the Angular application to authenticate against the Web API. Unfortunately I was seeing 401 Unauthorised when using the browser’s development tools.

image

 

After quite a lot of trying things out, I was stumped so I tried out debugging the WebAPI code running on Azure. Fortunately, Azure has some pretty cool development debugging tools.

To start debugging the API, I had to fire up Server Explorer. Apparently you should be able to use Cloud Explorer in Visual Studio 2015 but I have not been able to get this to work.

To debug your application do the following:

  • View->Server Explorer
  • Expand the Azure node in Server Explorer
  • Expand the App Service node in Server Explorer
  • Expand the resource group
  • Right click on the App and choose “Attach debugger”

image

The debugger takes a few moments to organise itself but eventually it will attach.

Now we can setup our breakpoints and start debugging the application. I put a breakpoint in the startup.cs file on the ConfigureAuth(app)  line within the Configuration function.

Even when I had the debugger running and tried to access the application, at no time did the breakpoint get picked up.

So what is going on?

I looked at the Azure configuration for the API application and made the following changes:-

  • Added a reply url for the Angular application which is currently being run using http://localhost:8080
  • Added an application permission so that the application can read directory data

This had no effect and I was still getting the error.

 

Examining the Angular Azure AD Application Configuration

Next I thought I better make sure that Angular is sending over an authentication token when making the request to Azure. For more information, watch this brilliant video on OAuth: Deep Dive into the Office 365 App Model: Deep Dive into Security and OAuth in Apps for SharePoint

 

I used the browser development tools and set a breakpoint in the settingsController.js on line 14 which is where the error is processed.

image

When the breakpoint is reached then we could look at the response object, fortunately the response object is pretty detailed and it has a config object which provides information about what was sent with the request. We can see here that there is a header object, now this should have an Authentication header with a Bearer token. There is not one, so what is going on? It must be our Adal Angular configuration.

 

Immediately when I saw this, I thought ah maybe its our endPoint configuration. There is a function as part of the Adal Angular service object, in our code that is adalService. This function is called getResourceForEndPoint(), this function will return back the App Id Uri based on a provided URL. Now interestingly, when this function was called with the following argument:

  • adalService.getResourceForEndPoint(“https://itsp365invoiceformappapitest.azurewebsites.net/api”);

This function returned null. This is very strange as our endPoints are configured. After a lot of playing about I realised my error. The configuration of the adalService is performed in app.js.

The problem was the object name given for endPoints. The object name should be endpoints. So the updated app.js  was changed to the following:

 

Now that we have this change made, I tried to login but got the error that the application could not reply back to the URL http://localhost:8080/app/

The fix was made to the Azure Application for the Angular client app, itsp365.invoiceformapp.client, by adding http://localhost:8080/app to the list of Reply URLs.

image

 

Whilst looking at this page, I realised that the client Angular application did not have any permissions to access the API Azure application. So to fix this, I added a new permission, chose the application:

image

Once this was added then the delegated permissions to access the application was given.

If we had not set this permission we would have seen the following error when trying to access the API application.

“response = “AADSTS65001: The user or administrator has not consented to use the application with ID = ‘{clientid}’”

 

So, actually these two changes really started to make a difference. Now when I accessed the settings view, we received the following error:

“AADSTS70005: response_type ‘token’ is not enabled for the application ↵Trace ID: 2c370e50-63ff-41e1-8cc1-fe90c8ef7b98 ↵Correlation ID: 0d1dd4db-cc4f-4bc1-b7c6-54812dfc3142 ↵Timestamp: 2016-05-14 21:35:39Z”

This requires the application manifest to be modified to enable something called the oAuth2AllowImplicitFlow.

image

 

This setting is changed by browsing to the itsp365.invoiceformapp.client Azure Application:

  • scroll to the bottom, click “Manage Manifest”
  • Click Download Manifest

image

  • Open up the downloaded file, this will have the filename of {clientid}.json, I use VS Code to do this.
  • Find the line below and change the false to true.image[27]
  • Save the file and then back on the Azure Application page choose Manage Manifest and click Upload Manifest

Wait for the manifest to be uploaded and processed.

Now when I made this change I kept getting the error “response_type token is not enabled…”. So I opened up the browsers settings and deleted the site cookies. This deleted the Azure AD authentication cookies and when I next opened up the Angular application I had to login. Now accessing the settings page, it worked!

So if you make changes , either do what I did above or run the browser in incognito mode to force an authentication.

Now the call to the configuration service API was successful!

 

Quick Refactor of the Application Constants

After I did everything, I was not happy with the way that the applicationConstants were part of the configurationService. This does not make sense so I moved them into their own folder and file. A file was created in /app/common/constants.js

The constants.js file had a new module called “applicationConstantsModule” and this defined the constant, applicationConstant.

You can see the code below:

 

I then had to update the index.html to load the /app/common/constants.js and also tell the invoiceFormApp to load the module, applicationConstantsModule within the app.js file.

 

With those changes made the refactoring is done.

 

Source Code

The source code for this blog post can be found in the following GitHub repositories:-

Conclusion

So now in this episode we have an application which has a basic REST API which is secured by Azure AD. We have made it possible for the Angular client to be able to authenticate against the REST API endpoint.

I hope you found this useful and there are some good resources for troubleshooting.

 

Next Episode

In the next episode, I will talk about my big mess up where I deleted the Azure AD app by mistake.

Thanks for reading, as always I would be interested in hearing what you think. Are these instructions useful, do they make sense?

 

 

Azure Active Directory Logo

Dev Diary: S01E05: Angular App – Setting up Azure Apps and ADAL.JS


Introduction

In the previous post we setup a page to add an invoice, adding the controller to manage that process. We explained in a bit more detail about the difference between factories and services. Hopefully, the explanation helped and made sense.

Anyway, today we are going to go and create our Azure Application, talk about setting up ADAL.JS. This will get us ready to create the Visual Studio 2015 project which will host the MVC Web API. This will be how we communicate with the Azure Document DB database.

Right lets get started.

 

Creating Azure Applications

Firstly, when ever I do this, I get it wrong and cannot remember what I need to do. Before we go into the detail, lets briefly explain what Azure Applications are and what it will do for us.

Also, I need to explain a bit about the design of the Azure Applications and how we are going to create two Azure Apps, one for the Angular bit and another for the Web API component.

 

What are Azure Applications?

Azure Applications are entities that are associated to an instance of Azure Active Directory. They can be found in https://manage.windowsazure.com by clicking the  Active Directory heading on the left hand side. Once we have loaded Active Directory, then we click on the name of the Active Directory item in the list.

image

The “Applications” tab contains the applications that you have available in your Azure AD.

image

Applications have various attributes including a Name, Sign-On URL, Client ID, App Id, Reply URL and also provide you with a way to manage permissions that users have when using this application.

Also, it is possible to assign whether someone has access to an application as well. By default, this capability is switched off.

We will explain the configuration in more detail shortly.

 

Why are we creating two applications?

We are creating two applications:

  • Angular SPA Web App
  • Web API MVC App

The two apps are one for the Web API service components and one for the Angular SPA Web App component. This allows us to manage who can access the Angular application  separately as to who can access the Web API.

Also this helps to keep the Web API component more secure as an app has a key which allows the application to be accessed and configured. By having two separate keys we won’t have the situation that the application cannot interfere with each other. Also the nature of an Angular component means it is client facing and so slightly less secure that the Web API component.

As we have support for new clients, then we can start creating new applications for each of the clients.

Anyway, lets get to creating the Azure Applications in our Azure Active Directory.

 

Creating the applications

To create the application, I browsed to https://manage.windowsazure.com and logged in with Work account.

image

Browsed to the Active Directory icon and clicked the link, next I opened my Active Directory Domain “iThink SharePoint”.

I clicked on Applications

This brings up the dashboard for the domain, which looks like below

image

From the footer, I clicked “Add” and chose “Add an application my organisation is developing”.

Then the following screen was displayed, a name was given to the application and the web application / web api option was chosen

image

Next we need to provide the Sign-On URL and App Id Url.

The Sign-On URL is the start page when the application needs to login and the App Uri Id, is the unique URI that that the application is identified with when trying to authenticate with the application.

image

The App Id Uri, should not be confused with the Client Id which is a GUID that we use to identify the application later on.

Now we click the tick box and the application is created.

Within our application we can see what the Client Id is by clicking on the Configure tab.

image

The example of the app shown below has been deleted but shows you all the settings.

image

image

The Reply Url section will need to be populated with the URLs that we are going to use to debug and test the application. These URL are trusted by the application as a URL that can be redirected to as part of the OAuth flow.

You can also upload a custom logo here, maybe we will do that when we get a bit further with the development of the app!

 

The section as the bottom is the Application permissions which we will cover this later.

image

 

The last point that I will make with this page is the Manifest button

image

We can use this to download and upload the application manifest. This can be used to configure additional application settings, that cannot be configured by the UI. An example would be , setting up custom application permissions. More on that later.

 

Now we have created one application, I could create one for the Web API application, but Visual Studio does a great job of setting these up so we will let it do its magic once we get to the Web API project configuration.

 

Adal.JS (Active Directory Authentication Library)

So now that we have the application, we need to setup Angular to use Adal to login.

I want users to login to the Angular client before they can use it.

This library allows us to integrate our application so that we can authenticate users with Azure AD.

As I have mentioned in my first post, we are using Adal.JS and the man with the knowhow is Vittorio Bertocci who has a great post, Introducing ADAL JS v1.

Adal.JS is packaged up for Angular as a bower package, so can be installed using bower install adal-angular. I have already done this in the client environment post.

Now that we have the adal-angular package installed in the solution, we can start to integrate it with our application.

 

Linking Adal.js into the application

First we need to add the Adal.js library so that it is referenced in our application. Next, we need to tell our Angular application that it is a dependency and then finally we can start to configure Adal. This will ensure that it knows about our application and where it is hosted.

Firstly, lets add the Adal.JS references to the application. This is achieved by the following to /app/index.html

/bower_components/adal-angular/lib/adal.js
/bower_components/adal-angular/lib/adal-angular.js
 

Adal Angular comes with two versions of the library, a minified version which is found in /bower_components/adal-angular/dist/ folder and a debug/dev version which is in the folder /bower_components/adal-angular/lib/ folder.

I am linking to the debug/dev version which is not minified but allows us to be able to debug what’s going on!

 

Ok, so now we have the library referenced in our application. We need to tell Angular to load it as part of its list of dependencies. To do that I modified the following line in /app/app.js  to add the dependency ‘AdalAngular’

 

var invoiceFormApp = angular.module(‘itspInvoiceFormApp’,
[
   ‘ngRoute’, ‘invoiceControllersModule’, ‘dataModelService’, ‘AdalAngular’
]);

Once we have the dependency, we are ready to setup Adal.JS configuration. How exciting!

 

To initialise the Adal,JS library it needs to know the following information.

  • instance – this is the Microsoft Azure login page to direct to, it always seems to be “https://login.microsoftonline.com/
  • tenant – this is the domain name for your tenant, so I have the domain ithinksharepoint.com so that is what I use it, but it might be something like company.onmicrosoft.com if you do not have a custom domain setup.
  • client id – this is the GUID that we saw when setting up the Azure Application, it is sometimes referenced to as the App Id.

image

  • endpoints – we will talk about these later but they allow us to map a URL endpoint to resource, so that Adal,JS can authenticate against the endPoint correctly.

 

Angular Constants

When I was looking at where to store this information, I did originally have it hardcoded into the /app/app.js file. However, after more reading and thinking I decided on another approach, using Angular constants.

To ease the configuration for the app, I decided to keep it all in one place and created  an object stored as a Constant.

This will be part of the configurationService module which we will complete later on but let’s create this constant first.

The configuration service module is going to live in /app/services/configurationService.js. So a new file was created and the following added

Please note that the clientId is not a valid one, but just shows you the value that you need to use.

Finally, we need to add the reference to the script in our /app/index.html file.

/app/services/configurationService.js

 

Configuring Adal.JS

As mentioned previously, there are some things we need to tell Adal.JS before it can do its magic. These are the instance, tenant and CliientId settings.

The following changes were made to the /app/app.js. file.

 

Error: Authentication Context is not defined

When I first put the code together, I got the error above. This was resolved by making sure index.html referenced both :

/bower_components/adal-angular/lib/adal.js
/bower_components/adal-angular/lib/adal-angular.js
 

Having Adal.JS installed also allows us to configure which routes require authentication, so we need to modify those too. This is achieved by adding the requireADLogin: true property to the route. Please refer to the app.js gist above for more info.

 

Changing the Homepage to handle Authentication

Now that we have the Adal.JS configured in our application, I thought I better handle authentication when the user hits our homepage.

So the following changes were made to the /app/contollers/invoiceControllers.js for the listInvoiceController.

 

Also, the following changes were made to list-invoices.html.

The changes use ng-hide to show the login button when the user is not logged in.

 

Note: whilst testing this I tried to upgrade to use 1.0.10 of Adal.JS but seem to have an error related to anonymousEndpoints. I am going to look into this but all was fixed when I reverted back to v1.0.8 of Adal Angular.

A couple of problems that I had included a fix to the Azure Application to allow add the redirectUrl: http://localhost:8080/app/index.html  to the list of Reply Urls.

image

Update this section of Azure Application configuration

image

 

 

 

Next Session

So we are now at at the end of the session, thanks for reading.

We have Adal.JS integrated and we have authentication, we are ready to start bring in the WebAPI MVC side. We can move the Invoices to be held in the API and start allowing us to create, edit and view the invoices.

I hope you find the information useful, please let me know if things are unclear or you need more information about anything that I have talked about.

The code that was commited for this episode can be found in Github: https://github.com/ithinksharepoint/IT365.InvoiceFormApp.Client/commit/e02ac5c2af67245cbd5bacd7886b96fb4406c148

Dev Diary: S01E04: Angular Services vs Factories & adding data to the underlying View Model from the View


Introduction

In the last episode, Dev Diary S01E03, we added our first Angular page and hooked up the application landing page with a view. This view then displayed some data.

Now I wanted to add a new page which allows me to add an invoice to the list of invoices. Also I think we need some navigation so you can get easily Add an Invoice.

 

Adding Invoice Feature

Add Invoice Page

So I added a new page called /app/views/add-invoice.html to my VS Code project.

This look as below

 

 

The page is used to create new Invoices. There are a few things to point out on this page.

We are going to have to tell Angular how to bind the view model to the various input form controls. This will allow Angular to pick up the values that the user puts into text boxes, date picker controls and applying those values to the model.

So how does this work, well there is the Angular directive ng-model.  This will bind the value of the control to the value inside the ng-model directive.

For example, line 22 we have the html :

 

 

The <input> control has ng-model=”invoice.reference” this will bind the value of invoice.reference to the text box control and also update the view model as the textbox changes. We will see later where that value coming from but this will be taken from our $scope.invoice.reference object found in the view model.

The other directive to mention is ng-click which binds the button’s click event is bound to an action or function found in the view model. In this case it will be bound the controllers, $scope.saveInvoice() function.

 

 

Another lovely feature of Angular is the ng-repeat directive which is used in the next code snippet to populate a drop-down list.

 

 

This will populate the drop-down list with a list of options for the types of units.

Now that we have the view created, I had to create the data model service, controller to manage the view and then setup routing.

$injector, $provide and Provider, Factory and Services

Before we move on to creating the Data Model Service. We need to talk about $provide. I had to create my first instance of a service and started by creating a  factory.

I could not get it to work how I wanted with the factory method and then after some further reading, I read about providers and service functions. This led me into looking into the various different methods that the $provide object implementation.

The Angular documentation on $provide gives some good information on this, but after reading I was a little confused about what the difference was between a factory and a service in Angular.

I  found this wiki article, Understanding Dependency Injection,  within the Angular GitHub project. It really was good explaining the concepts, under the hood mechanics and reasoning behind the approach in more detail.

The $provide methods are helpfully made as part of the Angular module object and you have the following types:-

  • provider – registers a service provider for the Angular $injector object. This is used to create and initialise a service.
  • service – registers the service, which is created by the service provider function. When a service is created there is also an associated service provider created with the name of ‘servicename’ + ‘Provider. e.g. DataModelService will have a provider called DateModelServiceProvider.
  • factory – this registers a factory function, which is called by the service provider.
  • constant – these are created as constants which allows them to be available as object which cannot be changed and are available for the lifetime of the application. I have not used these yet, but will get to use them shortly.
  • value – constants and values are very similar. The only difference is that constants can be used in service provider functions as part of the $provide.provider() flow. This wiki article on Understanding Dependency Injection talks about this further.

Anyway so what is the difference between a factory and a service? They are very similar and under the hood call the same $provide.provider function when created. The difference as I see it, is that a service can be initialised by a provider under the hood to return a singleton object for the service.

Whereas a factory is initialised by data which you pass into it. So a factory is great when you know that you will have the data to initialise it but you may not know what that is or have reference to it. This makes sense for a factory as that is what the factory pattern  does, create me something based on an argument that I pass into it.

The service pattern  create me an instance of a service but I don’t need to know the ins and outs of how to create that service. The service is initialised by the service provider function.

I hope that helps clear it up, I am sure that I will need to explain that again to myself.

Anyway, now that we have an understanding of the difference, lets create the Data Model Service.

 

Data Model Service

Firstly, let’s explain what the Data Model Service is. I am looking to create invoices. So I thought it would be nice to have a place or a service which I can use to create the objects that my application needs. So that is what the Data Model Service does, it allows me to create instances of my Data Model. This will include being able to create instances of the Invoice entity object and an Invoice has multiple Invoice Lines so I will need to be able to create InvoiceLines to add to the Invoice.

So let’s get started!

The data model service is implemented as a new module via a new file created at /app/services/dataModelService.js.

A new module was created called the dataServiceModule. The module creates an object and we use that object to create the provider and the service. Here is the implementation of dataModelService.js

 

 

A service in Angular has two parts, the service and the provider service. The service represents all the operations that can be perfomed by the service. The provider service is used to initialize the service.

Currently, in my DataModelService I have two functions

  • Invoice()
  • InvoiceLine()

Next, we will go through how I can then implement this service and make it available in the “Add Invoice Controller” which we will create next.

 

The Invoice Controller

So now we have a way to create our Invoice objects which is centralised. Next we can create the controller for using in the add-invoice.html view.

So our controller starts by creating the controller in file, /app/controllers/invoicecontrollers.js

The controller “addInvoiceController”, looks like this:

 

 

The other thing we must do is make sure that Angular is aware of our new module, so we need to add a reference to the JS file in index.html. Also we need to update the app.js so that the module, ‘itspInvoiceFormApp’ requires the module ‘dataModelService’.

 

 

With out this configuration, I was seeing the following error in the Chrome developer tool when trying to go to the add-invoice.html page.

image

 

Adding a new Invoice Line

We need to be able to add a new line to our invoice, we will probably need to remove them too but one step at a time.

The approach to adding these, is that we will create a button which will add a new invoice line. The button will call a function on our controller’s $scope object called addInvoiceLine().

This function will grab the $scope.invoice object and then will get an instance of a new InvoiceLine from our DataModelService. This object is then added to $scope.invoice.invoiceLines.

One of the great things is that Angular will pick up this change and will immediately update the UI to reflect the underlying objects, that is pretty cool.

 

Saving the Invoice

Currently the add invoice controller, does not do anything to actually save the invoice but rather pretends that it has been successful and then redirects the user to the homepage.

This is achieved by the controllers, $scope.saveInvoice().

The redirection is performed by the $location object. Pages are referenced within Angular, using “#” which represents the start homepage for Angular.

So we call $location.path(‘#’);  to return back to the homepage.

We are now done with our Add Invoice Controller, next I had to provide a way for users to get to the new page!

 

Adding the route

To handle directing the user to the add invoice page, add-invoice.html when the user goes to /invoices/add.

The following was added to app.js so that I had the following:

 

 

Now we need to provide a way to add an invoice, time for some navigation.

 

Adding Navigation

So, it is about time we have some navigation in our application. This will be added to the index.html  page.

We will add to links, one for the add invoice link and another to take you back to the homepage.

 

 

Using an <a> link tag to get to another page, is achieved using the <a href> element and using the special character # which represents the Angular home page. To go to the add invoice page we used, ‘’#/invoices/add”.

This gives us the following updated index.html page.

image

 

Github

You can find the code here, this commit represents the updates made to the repository for this post

https://github.com/ithinksharepoint/IT365.InvoiceFormApp.Client/commit/5f8afd7e3f2987603b6baa692faa1dcdd722c3d1

Next Episode

So we now have a way of adding Invoices to the page. It is about time that we start actually calling into our WebAPI hosted in Azure.

So next episode, I will explain what I did to create the Azure Application and then start to organise how we authenticate via ADAL JS.

As always please let me know what you think and if you have any feedback, let me know via the comments.

Dev Diary S01E03: Building the first Angular page


Introduction

In my previous post, Dev Diary S01E02, I explained the configuration of my environment for the client side. If you remember, I am building this application with Visual Studio Code and will also be building the server side component using Visual Studio 2015.

To be honest, I got impatient when developing this and decided that I would start to get to grips with the Angular part. I didn’t really understand things entirely but built my first page index.html.

 

Angular ng-app, ng-view and controllers

The Angular App Homepage (index.html)

So to get things running, I needed to reference the necessary components so that I could start to use them.

Angular is a JavaScript based Model View View Model based application framework which is used to build client side SPAs or Single Page Applications. We need a single page which is going to host the application. This is going to be our homepage, index.html.

Index.html had the following references added to load the Angular, jQuery, Bootstrap components. I added these under the closing tag as this allows the browser to load the page more quickly.


/bower_components/angular-route/angular-route.js
/bower_components/angular-resource/angular-resource.js
/bower_components/jquery/dist/jquery.js
/bower_components/bootstrap/dist/js/bootstrap.js

The other thing is that we need to tell Angular about the fact that this is an app and also tell it when to render the view.

Below is the index.html file

 

So you can see we have line #2 which an Angular directive, ng-app, which I will talk about a little later. This tells Angular that the application that will be loaded on this page is called itspInvoiceFormApp.

We have all the links to the scripts mentioned above and also the applications CSS for bootstrap.css and the application, invoiceformapp.css.

In the <body> tag, another Angular directive is added to a <div> tag. This is ng-view. This tells Angular where to render our view and provides the entry point for switching the content in our Single Page Application.

So now we have our index.html done lets move on to some JavaScript!

 

The Angular App Code (app.js)

Next, the Angular app was configured in /app/app.js. I had a look through the various examples on the Angular.js website and also out there via Bingle.

I added the following to app.js

 

 

So lets talk through this, the first line #1 is telling JavaScript to run in strict mode. This helps check for errors in the JavaScript, more information can be found here:

Line 3, creates a variable called invoiceFormApp using the angular.module() function. We pass in the name of the module, in this case ‘itspInvoiceFormApp’. The next parameter in the square brackets are the dependencies that the application relies on. This is important, Angular has this dependency injection engine, which we can take advantage of. In this case we are dependent on the Angular routing module, called ngRoute.

Next, I had to to configure the application, so create a function which provides the configuration of the app. From my limited experience, I know that this is going to change quite a bit as we start loading in more dependencies.

So the function currently has one parameter, this will increase as the number of dependencies get added to the application. The configurationProvider function has one parameter which maps to the invoiceFormApp.config() which is passing in the objects in the [‘$routeProvider’] into the function. So if we had the following [‘$routeProvider’, ‘myOtherThing’], then we would update the function assigned to configurationProvider to:

var configurationProvider=function($routeProvider,$myOtherThing).

 

Angular Routing

Anyway, I hope that helps clear that function up a bit, it took me a bit of time to get the hang of it. So within my app, I used the $routeProvider to create a route for ‘/invoices’. Now, when you setup a route you need to provide a couple of additional bits of information.

  • templateUrl: ‘[server relative url to the html file that is going to hold the view’
  • controller: ‘[name of the controller that will handle setting up the view]’

I setup the /invoice route to go to a view located at ‘/app/views/list-invoices.html’ and to use a controller named ‘listInvoicesController’. Notice the final call to .otherwise() on the $routeprovider variable this will cause the application to default to this route and page if there is no match found for the user’s input or the user is directed by the application to an invalid endpoint..

Now we have our routes setup, I had to give them something to point to.

 

Views and Controllers(View Model)

With the default route created,  next I had to create a view and a controller to implement the route.

 

View

Lets start with the view first, I created a view in VS Code called “list-invoices.html” in the /app/views folder.

Finally, we are getting to try out Angular. This page is being used just to view the data.

This is what I ended up putting together for list-invoices.html.

 

 

So basically I have a table wrapped up in some <divs> the outer <div> has the class name container, this is a bootstrap thing to demark the content that is to be styled by bootstrap, the inner div with the class name row creates a new row.

Now on to the actual Angular stuff. we have these various tags starting with “ng-“, these are called directives and allow you to do something with the data that you have bound to the page from your controller and data, or model.

The example that we can see is ng-show   (ine 5) this points to something in or model which evaluates to a boolean value and will display that <div> element when it evaluates to true.

I think this is pretty cool stuff, I was always amazed when I saw this kind of thing with Knockout.js

Anyway, so next we render our data, so we have a table which has been tagged with various bootstrap classes to make it responsive. At some point I am sure I will have to work out the responsive stuff works. The cool bit with the table, starts at row 16.

We have a line which reads <tr class=”clickable-row” ng-repeat=”invoice in invoices”>. So this Angular directive ng-repeat allows us to loop through an array of objects which are in an array called invoices.

This <tr> element block will get repeated for each invoice in invoices, within the <tr> we have a number of <td> elements which are being used to display the values in the properies found on the invoice  object. This is one way that Angular does its data-binding. So using {{invoice.invoiceDate}} we can display the contents within the invoice object.

The rest of the page is pretty uninteresting, I did also add a section to display errors which is quite neat and shows another thing that you can do with Angular directives which is actually add logic within the directive. So we have a <div> tag which has the ng-show  directive set to ng-show=”error!==’’”. So if there is an error in our data model then this div will show the error.

Anyway, so until I show you the controller, it does not really make sense as how do we know what data we are binding to the view?

 

Controller and Model

In order for the view to work we need to create a controller and also the model that the controller is going to pass into the view.

I created a file called invoiceControllers.js in the /app/controllers folder.

Within this file, I created a new module which created a module called InvoiceControllerModule. Then we registered a factory called invoiceController. I have to say that I now know that this was a mistake. But at the time I didn’t realise it. I will talk about the changes that I made in a later blog post.

Anyway, now that we have the factory we need to create a function which is called when the factory is initialised.

 

 

Note that the factory method takes a function and the parameters match the attributes defined in []. This controller is taking just a $scope variable.

Actually the $scope variable is very important and represents the view model which can be referenced within your (.html) view file.

We created a couple of properties of the $scope object to hold an error and also to hold a list of invoices.

Next, we need to add some invoices to the array, so that we have something to display.

To keep things easy I just created a load() method on the $scope object to load the data.

This now creates a controller which exposes a $scope variable, final file looks like this.

 

Now, that this is all put together it generates a page which looks a little like this.

image

 

Make sure that if you are loading some data n your controller with a load() function, that you call it. I spent a couple of minutes, wondering why I did not have any data loaded and the realised I hadn’t actually called the function.

 

When testing and debugging use http://localhost over http://127.0.0.1

Something that I noticed with Google Chrome when testing the environment is that the css would not work correctly if I tested using http://127.0.0.1:8080 so I ended up using http://localhost:8080 which caused the styling to render correctly.

 

Next Episode

I hope you found this useful, please let me know if there is something that needs more clarity.

I have moved this code into GitHub and it is currently available here:

https://github.com/ithinksharepoint/IT365.InvoiceFormApp.Client/tree/master

In the next episode we are going to put together some add functionality and also configure the application navigation.

Dev Diary S01E02: Angular / WebAPI / Azure Document Db App – Client Environment Setup


Introduction

In my previous post: Dev Diary Entry 1: Azure Web App with MVC WebAPI, Angular and Azure DocumentDb, I introduced the Invoice Management App that I am planning to build.

For complete transparency, the application that I am talking about building has been in development for a week or so now. So, as I write this I am playing catch up. I have been writing down all the problems that I have had and how I resolved them. My aim is that we will quickly get up to date so that I am coding and then I can quickly write about what I did.

Today, we are talking about setting up Visual Studio Code and Visual Studio 2015 to host my applications. Remember we are building two components, the Angular client application in Visual Studio Code and the MVC Web API component using Visual Studio.

 

Setting up the Environment

Visual Studio Code

Developing in Visual Studio Code is quite different to using Visual Studio, the team at Microsoft are doing a great job at improving the application but it does feel very unfamiliar to me who has been using Visual Studio for a rather long time.

Anyway, I downloaded VS Code from http://code.visualstudio.com/ and installed it on my machine.

I am developing on a Surface Pro 4 with Windows 10 x64. So the instructions provided are for Windows but it is pretty similar for MAC OSX and Linux.

 

Developer Directories

I am developing in the c:\dev folder and have created a subfolder called ITSP and then a subfolder, VSTS. The final directory is c:\dev\itsp\vsts

 

Node and NPM

The next step, was setting up the environment, I had spoken to a few people and read a few posts and the way to go with VS Code was using Node.js tooling and the Node Package Manager, npm.

Node provides a few lightweight services which we can take advantage of when developing. The one that I make most of is the built in HTTP server, but more on that later.

NPM or Node Package Manager provides a fantastic way of downloading, installing and keeping your dependencies up to date. I guess the name came from Redhat’s Package Manager or RPM. To be fair it is also like NuGet which the .NET world have been using to keep their dependencies in check.

So I downloaded and installed Node from https://nodejs.org/en/ and choose the latest build which was v5.6.0, I see that version v6 is out as I write this. The download is an MSI so was a quick simple install.

Next is NPM, so actually NPM comes included with Node.js but I wanted to make sure that I had the latest version of NPM. This is the advice in the NPM Installation instrucitons found here: https://docs.npmjs.com/getting-started/installing-node

So to do that I started the Node,js command prompt

  • npm install npm –g

The command calls npm telling it to install a package called npm with –g which means to install it so it is available globally.

 

Bower

The other tool that seems to be great at dependency management is Bower. Now, I had a hard time working out what the difference was between Bower and NPM. Why do I need both. Well Bower seems to be better at installing and configuring the client side components and NPM for the server side components.

One of the reasons that I have chosen Bower is to be honest a lot of tutorials use it. Now, this is something that I will look into a little later on the project but I want to get up and running. There do seem to be a lot of alternatives such as Browserify and Webpack.

 

Angular

So this is my first project using Angular, I hear people talking about it all the time! As I was researching into the product more it became embarrassing to see how long its been out before I have had a go at using it!

One of the chaps speaking about this stuff from the SharePoint world is Andrew Connell via his blog. He has a great amount of content which I found really useful.

As I mentioned in my previous post, I have been reading up on Angular via their documentation pages. I also have been listening to Scott Allen’s AngularJS: Getting Started on Pluralsight.

 

Bootstrap

As a developer, I need help with design so I have decided to use Twitter Bootstrap and fortunately this is quite easy to include in your project.

I am sure that you have used Bootstrap more than me!

However, Bootstrap is a framework which provides a grid based system for defining responsive designs based on having different css classes for different screen sizes.

I have to say I am always amazed what front-end developers can do with Bootstrap, I am sure in time that it will become second nature.

 

Yeoman

Yeoman is like File->New Project in Visual Studio. It is pretty cool actually and allows you to create or use pre existing templates to make the project scaffolding. I did look at this and various templates but I found them complex and they started to pull in a lot of stuff which I did not know about.

So to kept it simple, I haven’t used Yeoman as I wanted to learn how to build the project from scratch rather than have a tool do everything for me and I then don’t understand my dependencies.

I am sure that I will change my behaviour next time once I understand how everything fits together.

Adal.JS

Now I know that I am going to be using Azure Active Directory as my authentication and authorisation mechanism.

ADAL is a library that has been created which provides a wrapper to manage authentication with Azure AD. The library is superb and really straight forward to use for the .NET stack. Fortunately, there is also a JavaScript implementation called Adal.js and even better there is a module created for Angular!

I have been following Adal for a while and the go to guy is Vittorio Bertocci, he has some great posts on all things ADAL.

Introducing ADAL JS v1

The article is great and talks about how to install the framework using Bower and then provides examples including one for authenticating your application with Angular!

 

jQuery

Of course we need jQuery, I don’t think this framework needs any introduction.

This was installed from the node.js command line:

  •  using bower install jquery

 

 

 

Creating the Client Side Visual Studio Code Project

Ok so now I have talked about all the bits and pieces that I am using for the client side of the application, I will try and explain the steps that I took to create the project for Visual Studio Code.

Remember we have two components in this application:-

  • Angular Client side application being developed in Visual Studio Code
  • MVC WebAPI Server side application being developed in Visual Studio 2015

So,  to create the Visual Studio Code project you need to create a package.json file. This is the equivalent of a Visual Studio csproj file for Visual Studio C# Projects. It contains the version number, name of the project, description and also it has scripts section where you can define commands to perform actions when developing your application.

So to get started I did the following:-

  • started node.js command prompt
  • created a directory c:\dev\itsp\vsts\IT365.InvoiceApp.Client
  • from the directory just created I ran npm init
  • this wil start a wizard which then asks for various information about the project including its name, description and author details

Now that we have our package.json created we can fire up Visual Studio Code

  • code .

This will start Visual Studio Code in the current directory which will cause Visual Studio code to read the application information created so far.

 

Install Dependencies

Now we have the project created next it is time to bring in our dependencies.

We will use npm and bower to pull in the dependencies:-

  • bower install bower-angular
  • This will install the Angular component into our project into a folder called bower_components\angular
  • Angular Route
  • bower install bower-angular-route
  • This will allow us to define our routes in the application so that we can control where the user goes, what they see and which controller to use. More on this later
  • Angular Mocks
  • bower install bower-angular-mocks
  • This will allow us to do Test Driven Development when we start looking at Continuous Integration and Continuous Delivery
  • Angular Sanitizer
  • bower install bower-angular-sanitizer
  • This helps us to strip out dangerous characters from when parsing HTML

 

  • Bootstrap
  • bower install bootstrap
  • This will give us a better look and feel than I could do!

So, we have the Angular and Bootstrap stuff installed that I thought we needed.

 

Next we need to install the ADAL JS stuff

  • ADAL JS
  • bower install angular-adal
  • This will allow us to manage the login / authentication, authorisation process in our application with Azure Active Directory

Then we have jQuery

  • bower install jquery

 

Finally, I want to be able to actually run the application locally and a really nice way of doing that is using the Node.js HTTP Web Server, http-server

  • Node http-server
  • npm http-server –g
  • This will install the http server globally so we can use it in our next applications

 

Create Application Structure

Next I created the application structure

So the following directories and files  were created from within Visual Studio Code

  • [app]
  • [controllers] – this will hold all our controllers
  • [services] – this will hold all our services
  • [entities] – this will hold our JavaScript objects relating to entities such as Invoices, Users etc
  • [views] – this will hold all our views
  • [css] – this will hold our CSS styles
  • [images] – this will hold our image
  • app.js
  • index.html

I am sure that I will be adding more folders etc but that gave me something to start with.

 

Trying out the Application quickly

So one of the tips that I picked up from the node.js documentation was how you can create tasks with NPM.

I was a little confused by this to be honest but after a bit of investigation I found out that I could modify the package.json to configure these tasks for NPM to be able to use.

  • Opening up package.json, i found the scripts section and added the following
  • When i first did this i added just the http server –a 127.0.0.1 –p 8080
  • however, after more reading I realised I could run multiple commands using the && syntax
  • So we ended up with

npm-start-task-config

 

Now this is pretty cool, from the node.js command prompt I can type

  • npm start

This will start a web server and fire up the browser taking me to the homepage!

image

 

Next Episode

So in the next episode, we will actually start develop something. I was pretty excited to try out Angular so I just started to build the application using client side data. So we will cover that.

I hope you can join me for the next episode.