Pass ASP.NET Core Appsettings Values to Angular

As part of getting my set of Identity Server 4 sample applications to run in Azure, I needed a way in the Client Application to pass some configuration values from  appsettings.json to the Angular front end that could be used both during server-side rendering and client-side rendering. This application is using JavaScriptServices. This solution may need tweaking if your application isn’t using JavaScriptServices. The code for the client application can be found here.

Settings

In this example, we need to pass the address of our Identity Server and API from  appsettings.json to Angular. The following is the settings file for this example.

Providing Configuration Data to Angular

In this application, Angular is loaded from the index action of the home controller. This view can be found in the  Views/Home folder in the  Index.cshtml file. The following is the file before any changes.

The first change needed is to inject the configuration data using ASP.NET Core’s DI system. Add the following two lines at the top of the file.

Now the configuration data from the application is available to this view. Next, we need to pull a couple of values out of the configuration data and pass it to the Angular application. To do this we are going to use the  asp-prerender-data tag helper. You can read more about it in the official docs. The idea is you construct an object which is then serialized and stored in  params.data. In our example, we are passing the URLs for the Identity and API Applications.

The above is creating a new object with an  apiUrl property and an  identityUrl property. The following is the full completed view for reference.

Angular Server-Side Boot

When Angular gets prerendered on the server-side it runs the code in the  boot.server.ts file. This is where we will set up the providers needed on for the server side prerender. This is the bit that I missed for the longest time when trying to get this example going. I kept trying to find a way to add the providers in the  app.module.server.ts file. Add any providers you need to the  providers constant. For example, the following is passing URLs for an API and Identity Server in addition to the defaults provided by JavaScriptServices.

Lower in the same file we can pass through the configuration values to the client side render as globals on the window object. To do this add a  globals property to the object being passed to the  resolve call.

The above will have the URLs as part of a single object, but you could have each URL as its own property if you prefer.

Angular Client-Side

Now that the server-side has providers for API URL and Identity URL we need to provide the client-side with the same capabilities. These changes will be in the  app.module.browser.ts file. The first step is to add providers for each.

Next, we need functions to return the URLs from the  url_Config property of the window object which the following two functions do.

Wrapping Up

With the above, you can now use your configuration values from ASP.NET Core and pass them through to your Angular application. In hindsight, the process is pretty simple, but getting to that point took me much longer to figure out than I would like to admit. I hope this post saves you some time!

Identity Server: Changing Angular OpenID Connect Clients

Thanks to Andrew Stegmaier opening this issue on the repo that goes with my IdentityServer exploration I was made aware of a certified OpendID Connect client specifically written for Angular (4+). The angular-auth-oidc-client was created by damienbod. This post is going to cover the transition to this new client. The starting point of the code can be found here. All the changes discussed in this post take place in the ClientApp project.

Package Changes

In  package.json the following changes need to be made using your package manager of choice or manually changing the fill and doing a restore.

App Module Changes

Both  app.module.client.ts and  app.module.server.ts got a little cleanup to remove the duplicate provider code. The following lines were deleted from both files.

The  providers array moved to using providers imported from  app.module.shared.ts.

Next, in  app.module.shared.ts the following imports were removed.

Then, the following import for the OpenId Connect client was added.

In the  declarations array  CallbackComponent was removed. In the  imports array  AuthModule.forRoot() was added. The route for  CallbackComponent was removed and the  canActivate condition was removed from the  fetch-data route. Finally, the  providers section is reduced to only the  AuthService. That was a lot of changes, so I am including the full finished class below.

File Deletions

The following files were completely removed. Some of them may come back in a different form, but for the moment the functions they were handling are being dealt with in a different way.

Auth Service

The  AuthService class was pretty much rewritten since it is at the core of the interaction with the OpenId Connect client. It still contains pretty much all the functionality as before just using the new client. The following is most of the class. I removed all of the HTTP calls except for  get to save space.

It doesn’t show the best in the world here so be sure and check it out on GitHub. All the IdentityServer configuration is done in the  constructor using the  OpenIDImplicitFlowConfiguration class.

Navigation Component

The  NavMenuComponent class now needs some changes to match the new  AuthService. First, the following change to the imports.

The  AuthService class now provides the ability to subscribe to changes in the user’s authorization. To handle the subscription and unsubscription the class will implement both OnInit and  OnDestroy. Here is the new class declaration.

Next, here is the implementation of ngOnInit which handles the subscription to the change in  isAuthorized.

Then,  ngOnDestroy handles the unsubscription.

The class level variable for  _loggedIn is replaced with the following two variables.

The  constructor has been greatly simplified and now only takes an instance of the  AuthService.

Finally, the  login and  logout functions have changed to match the new function names in the  AuthService class.

Navigation Component UI

In the  navmenu.component.html file, a couple of tweaks are required based on the new variable names used above. The first set is related to showing either Login or Logout.

The final change in this file was to make the link to  fetch-data only show if the user is logging instead of sending the user to an unauthorized view.

Fetch Data Component

The final changes for the conversion to the new client are in the  fetchdata.component.ts and they are only needed because of a rename of the HTTP Get helper in the  AuthService.

Wrapping Up

This change took a lot of changes, but in the long run, it is going to be a better choice since the new client is focused on Angular. Another great thing about this client is they are looking into ways to handle the first load not remembering the user is logged in due to server side rendering (issue #36).

The finished code for this post can be found here.

Identity Server: Redirect When Route Requires Logged in User

This post is going to continue where the series on IdentityServer4 left off, but I am not officially making it part of the series. There may be a few posts like this where I improve on the example applications from the series. The starting code for this post can be found here.

All the changes in the post are in the Client Application from the sample linked above. I did some cleanup on a couple of files so if you are looking for the differences keep in mind most of the changes are a result of the cleanup.

Unauthorized Component

The first step is to add a new component that will be shown to the user when they navigate to a page that requires them to be logged in but they are not. Add a  unauthorized.component.html file to the  ClientApp/app/components/unauthorized/ directory with the following contents.

This will tell the user they need to log in and provide a login button and a button to go back to the previous page. Next, add a  unauthorized.component.ts file to the same directory. This class will handle the clicks from the view.

This class is using the  AuthService for login and Angular’s  Location class to move back to the previous page.

New Component Usage

Now that this new component exists it needs to set up in  app.module.shared.ts. First, add an import.

Next, add to the  declarations array.

Finally, add unauthorized to the routes array.

Now that this new component is in place how does it get used? Well, any route that has  canActivate:[AuthGuardService] will require the user to be logged in to activate. For example, the  fetch-data route above won’t activate unless the user is logged in.

Auth Guard Service

AuthGuardService is an existing class in the project. The following is the full file.

As you can see in the  canActivate function if the user is logged in then the function returns true otherwise, the user is routed to the unauthorized component. Before the changes in this post, this dropped the user back on the home page since the unauthorized component didn’t exist.

Wrapping up

With the changes above the user gets a slightly better experience. Just being dropped on the home page wasn’t very helpful as to why that was happening. This at least lets the user know they need to log in. Another option could be to hide the navigation for the routes they don’t have access to until they log it.

The finished version of the code can be found here.

Identity Server: Calling Secured API from Angular

This post is a continuation of a series of posts that follow my initial looking into using IdentityServer4 in ASP.NET Core with an API and an Angular front end. The following are the related posts.

Identity Server: Introduction
Identity Server: Sample Exploration and Initial Project Setup
Identity Server: Interactive Login using MVC
Identity Server: From Implicit to Hybrid Flow
Identity Server: Using ASP.NET Core Identity
Identity Server: Using Entity Framework Core for Configuration Data
Identity Server: Usage from Angular

This post is going to take the solution from last week, the code can be found here, and add an example of the Client Application (Angular) calling an endpoint on the API Application that requires a user with permissions.

API Application

To provide an endpoint to call with minimal changes this example just moves the SampleDataController from the Client Application to the API Application. The following is the full class.

Make special note that this class now has the  Authorize attribute applied which is the only change that was made when moving the file from the Client Application. This attribute is what will require an authorized user for all the routes this controller services.

Client Application

In the Client Application, the first step is to remove the  SampleDataController since it is now in the API Application.

Next, in the  app.module.client.ts file, add a new provider which can be used to supply the URL of the API to the rest of the Client Application. Don’t take this as best practices for injecting configuration data it is just an easy way to handle it in this application. The following is the full class without the imports (which haven’t changed) the new item is the  API_URL.

Now for the changes that need to be made to the  FetchDataComponent which is the class that will call the new API endpoint. First, add an import for the  AuthService.

Next, there are a couple of changes to the signature of the constructor. The first is to use  'API_URL' instead of  'ORIGIN_URL'. The second is to provide for injection of the  AuthService. The following is a comparison between the version of the constructor signature.

The final change is to use  authService.AuthGet with the new URL instead of  http.get.

With the above changes, the user has to be logged in or the API will respond with not authorized for the weather forecasts end point. The Client Application doesn’t have anything to provide the user with the fact they aren’t authorized at the moment, but that is outside the scope of this entry.

So far we haven’t look at the code in the  AuthService class, but I do want to explain what the  AuthGet function is doing and the related functions for put, delete, and post. These calls are wrappers around the standard Angular HTTP library calls that add authorization headers based on the logged in user. The following is the code of the  AuthGet as well as two helper functions the class uses to add the headers.

Wrapping up

It feels like this application is finally getting to the point where other development could happen if it were more than a demo, which is exciting. My thought on how this could be used for real applications is the Identity Application would stand on its own and be used by many clients. The Client Application with a few more tweaks could be used as a template for Angular applications. The completed code can be found here.

This post finishes up the core of what I set out to learn about IdentityServer, but there could be more related posts as I continue to add some polish to the current implementation of the sample solution.

Identity Server: Usage from Angular

This post is a continuation of a series of posts that follow my initial looking into using IdentityServer4 in ASP.NET Core with an API and an Angular front end. The following are the related posts.

Identity Server: Introduction
Identity Server: Sample Exploration and Initial Project Setup
Identity Server: Interactive Login using MVC
Identity Server: From Implicit to Hybrid Flow
Identity Server: Using ASP.NET Core Identity
Identity Server: Using Entity Framework Core for Configuration Data
Identity Server: Usage from Angular (this post)

This post is finally going to add login from Angular in the Client Application. It has been a long time coming and will be a starting point, based on a few examples I found which I will list at the end. The starting point of the code can be found here.

API Application

In order for the Client Application to be able to call the API Application, there are some changes needed to allow cross-origin resource sharing. For more details check out this post only the basics will be covered here. First, add the following NuGet package.

  • Microsoft.AspNetCore.Cors

Next, in the  ConfigureServices function of the  Startup class add AddCors before AddMvc. The following is the full function. This allows calls to the API Application from the Client Application which is running on localhost on port 5002.

Then, in the  Configure function add  app.UseCors("default"); to make sure the default policy defined above is enforced. The following is the full function.

Identity Application

The Identity Application doesn’t have a lot of changes, but some of the configuration between it and the Client Application is what took me the bulk of time getting the code for this post setup and going.

If you are keeping up with the series then last you will know last week all the configuration data was moved to a database using Entity Framework Core. This is a bit of a problem now that I need to add a new client and the configuration data doesn’t any associated UI. To work around this I just added the new client to the  Config class in the  GetClients function and then deleted the existing database and let Entity Framework recreate it based on the new seed data. Not optimal, but I didn’t want to complicate things by adding a UI for the client setup. The following is the new client.

There are a few things in this configuration that took me some time to get right. First of all best, I have been able to tell with this style of application implicit flow is the way to go which is handled by using a  GrantTypes.Implicit for the  AllowedGrantTypes.

The next issues I ran was a cross-origin resource sharing issue. Thankfully IdentityServer makes it easy to specify what origins should be allowed using the  AllowedCorsOrigins property. In this example, we want to allow requests from the URL of our Client Application which is http://localhost:5002.

The last issue I had on was with the URIs I had set. The configuration in IdentityServer needs to exactly match the setup in the Client Application or you will have issues. I also had trouble trying to use the raw base address (http://localhost:5002) as the  PostLogoutRedirectUris so look out for that as well.

Client Application

In the client application open the  package.json file and add the following the  dependencies section.

I also updated the typescript version to 2.3.4. Be cautious when changing the version of typescript as there is an issue with Angular and typescript 2.4.x at the moment.

At this point in the process, I had to find some resources on how to continue. The following are the ones I leaned on most.

ANGULAR OPENID CONNECT IMPLICIT FLOW WITH IDENTITYSERVER4
ASP.NET Core & Angular2 + OpenID Connect using Visual Studio Code
Repo for the previous link
Repo for with example Angular OidcClient

Getting this part of the application working involved a lot of changes and instead of going in depth on everything I am going to recommend just copying in the following files for the finished example code and dig more into them after you get an example working. Here is the list of files.

  • ClientApp/ClientApp/app/components/callback/callback.component.ts
  • ClientApp/ClientApp/app/components/services/ – whole directory
  • ClientApp/ClientApp/boot-server.ts – related to a typescript error only if needed

With the above files in place, we will now focus on using the functionality they provide to log in and protect routes. To begin   app.module.client.tsapp.module.server.ts and  app.module.shared.ts all need the next set of changes. I haven’t tried it yet, but I bet this change could just be made in the shared file and used in the other two. Add the following imports.

Next, add the same three items to the array of providers (or add one if it doesn’t exist). The following is an example from the shared file.

Finally, in the shared file change any routes that you would like to require the user to be logged in to be like the following which utilizes the  canActivate of the route.

In the  navmenu.component.html which is the UI for the navigation menu add the following two options to the unordered list.

The user will only ever see one of the above options based on being logged in or not which is what the  *ngIf is doing.

The navigation view model ( navmenu.component.ts) changed a bit more. The following is the complete file.

New imports were added for the  AuthService and  GlobalEventsManager which get injected into the constructor of the class. The class also contains a _loggedIn property to track if the user is logged in or not. Finally, functions were added for  login and  logout to go with the two new links shown in the navigation.

Wrapping up

With the above, the Client Application can now log a user in and out utilizing IdentityServer from Angular. There are a lot of details in the files we just copied, but with a working sample, it is much easier to examine/customize how the process is being handled. Check back next week to see how to call the API Application from the Angular part of the Client Application.

The completed code can be found here.

Identity Server: Sample Exploration and Initial Project Setup

This post will be a continuation of my exploration around Identity Server which was started with this post which was more of an overview of the space and my motivations for learning about Identity Server. There were a lot of things that were unclear to me as I first started looking through the samples so this post is going to communicate so of those issues and hopefully clear them up for you as well.

After this post, the follow-up post should be more focused on one thing instead of trying to cover so much information in on go.

The following are all the posts in this series.

Identity Server: Introduction
Identity Server: Sample Exploration and Initial Project Setup (this post)
Identity Server: Interactive Login using MVC
Identity Server: From Implicit to Hybrid Flow
Identity Server: Using ASP.NET Core Identity
Identity Server: Using Entity Framework Core for Configuration Data
Identity Server: Usage from Angular

Typical Sample Solution Structure

I started my exploration with the IdentityServer4.Sample repo specifically in the Quickstarts folder. For me, this was a mistake as I didn’t have a good enough grasp on the larger concepts for the code to provide proper guidance. Big surprise here, but using the docs and actually walking through the project creation was very helpful.

The code associated with this blog can be found here. The solution contains three projects.

  • ApiApp – Backend for the application and is a resource that is will require authorization to access. The API will be an ASP.NET Core Web API.
  • ClientApp – Frontend application that will be requesting authorization. This is an ASP.NET Core application that is hosting an Angular (4) app.
  • IdentityApp – This is ASP.NET Core application that is the IdentityServer and will end up authorizing users and issuing tokens for resources.

Identity Application

For the Identity application, create an ASP.NET Core Web Application using the empty template targeting at least ASP.NET Core 1.1. Next, using NuGet install the IdentityServer4 NuGet package.

Now that the IdentityServer4 NuGet package is installed open up the Startup class and add the following to the ConfigureServices function.

The above registers IdentityServer with ASP.NET Core as a service available via dependency injection using temporary and in-memory components as a stand in for testing. The Config class used here will be added a bit later.

Next, the Configure function should look like the following.

The above is a basic Configure function.  app.UseIdentityServer() is the only the only bit related to IdntityServer and it is adding it to the application’s pipeline.

The final part of this application is the Config class which is used to define the in memory test resources for this application. As you can see below it is defining both API resources and Clients. In the future theses, items would be pulled from a datastore.

API Application

For the API application, create an ASP.NET Core Web Application using the Web API template targeting at least ASP.NET Core 1.1. Next, using NuGet install the IdentityServer4.AccessTokenValidation NuGet package.

Ater the above NuGet package installed open up the Startup class. In the Configure function, the IdentityServer middleware needs to be added to the application pipeline before MVC using the app.UseIdentityServerAuthentication function. The following is the full Configure function.

Notice that the address of the of the authority must be specified (this will need to be the address the Identity Application is running on) as well as the ApiName matches the API Resource we added in the Config class of the Identity Application.

Next, in following the IdentityServer quickstart docs add a new IdentityController to the project. Just to be 100% clear this is just a test endpoint to show how to require authorization on a controller and isn’t something that is required to use IdentityServer. The controller has a single Get that returns the type and value of all the user’s claims.

The [Authorize] attribute on the class is the bit that requires calls to this endpoint to have authorization. Keep in mind that the same attribute can be left off the class level and added to specific functions if the whole controller doesn’t require authorization.

Adding the [Authorize] attribute means that the IdentityServer middleware we added in the Startup class will validate the token associated with the request to make sure it is from a trusted issues and that it is valid for this API.

Client Application

For the Client application, I deviated from the samples a bit. Instead of just creating a new MVC application I used JavaScriptServices to generate an Angular (4) application. If you want detail on how that is done you can check out this post (yes it says Angular 2, but the newest version of JavaScriptServices now outputs Angular 4 and the steps haven’t changed). An Angular application is my end goal and why I made this deviation from the samples.

After the Client application has been created use NuGet to add the IdentityModel package. This package is to make interacting with the Identity Application simpler.

For this first go instead of actually interacting with the Identity Application from Angular I will be using it from MVC instead. The detail of interaction from Angular will come in a later post. The IdentityController is what does the interaction with both the Identity Application and the API Application interactions in this version of the client application. The following is the full IdentityController class.

In the above, you can see the IdentityModel in action. Using the DiscoveryClient means the client application only needs to know about the root address of the Identity Application. TokenClient is being used to request a token from the Identity Application for the clientApp using the client secret which in this case is actually the word secret. Keep in mind in a real application secrets should be kept using the ASP.NET Core Secrets manager, see this related post. Also, take note that clientApp and secret are the values that were defined in the Config class of the Identity application.

The rest of the code is taking the token response and making a call to the API application with the response from both of those calls being stored in ViewData for display on the view associated with the controller.

The view is just an Index.cshtml file in the path Views/Identity. The following is the full view.

It isn’t pretty, but the whole point of this controller and view is just for verification that the three applications are properly communicating with each other.

URL Configuration

In this setup, it is important that the URL for the Identity Application and API Application be fixed so they can be accessed by the client. In a more production level application, these values would at a minimum need to be in configuration. The following is the setup used for this solution.

  • Identity Application – http://localhost:5000
  • API Application – http://localhost:5001
  • Client Application – http://localhost:5002

There are a couple of ways to configure test values. The first is to open the project properties and select the Debug tab and set the App URL.

The second option is to go to the Program class for each project and add a UseUrls to the WebHostBuilder like the following.

Wrapping up

After going through the above process I now have a much better understanding of how the very basic setup using Identity Server should work. I hope if you made this far you found some helpful bits.

There is a bit of strangeness using Visual Studio to try and launch all three applications and can result in an error message if multiple of the projects are run in debug mode. For the most part, this can be worked around by only debugging one application at a time. It is a bit annoying at the beginning stages, but once an applications gets past that point I imagian that the Identity Application won’t require much debugging.

If there are any questions please leave a comment and I would be happy to try and help. The finished code can be found here. This basic example will be expanded over time and all the related entries can be found in the IdentityServer category.

Upgrading a JavaScript Services Application

As part of the ASP.NET Core Basics series of posts, JavaScript Services was used to create a couple of front end for a basic contacts API using Aurelia and Angular 2. Theses applications were created a few months ago and JavaScript Services has kept moving since then. This post is going to look at one strategy for taking an application created on an older version of JavaScript Services and update it to match the current version. This post will be following the upgrade of the Angular project from ASP.NET Core Basics repo with the starting point of the code being from this release.

The strategy

One of the considerations when doing this upgrade was getting the changes that happen on the ASP.NET Core side of the application and not just the JavaScript bits. In order to make sure that nothing was missed I decided to use JavaScript Services to generate a new application and use that to compare with the implementations in the existing application.

Create comparison application

This is going to assume JavaScript Services is already installed. If it isn’t this page has instructions or this post has sections that deal with creating a new application using JavaScript Services.

The update

Following is the files that changed during this update. This is also the list of files I would check anytime an upgrade needs to be done.

There were a fair amount of changes in the files listed above and instead of posting the code the differences can be found here. The previous diff didn’t contain the webpack.config files and those diffs can be found here and here.

After all the files have been updated make sure to run the following command from a command prompt in your project directory to make sure webpack has vendor related items regenerated.

Wrapping up

This post is a lighter on the details that I do most of the time, but this type of upgrade would just have been a wall of code and not been overly useful and the commits on GitHub are a much better guide to what the upgrade looked like. My feeling is that over time the number of changes going forward may end up being smaller and easier to integrate.

Both the Aurelia and Angular projects have been upgraded and the final version of the code can be found here.

Angular 2 Contact Creation and Post to an API

Expanding on this post which created a placeholder for creating new contacts this post will create an actual UI and post the newly created contact to an ASP.NET Core API. The code before any changes can be pulled using this release tag. Keep in mind all changes in this post take place in the Angular project if you are using the associated sample.

Contact service changes to all post

The contract service found in the  contact.service.ts file of the  ClientApp/app/components/contacts/ directory is used to encapsulate interaction with the associated ASP.NET Core API and prevent access to Angular’s Http library from being spread across the application. The first change is to expand the existing import of Angular’s Http library to include  Headers and  RequestOptions.

Next, a  save is added that makes a post request to the ASP.NET Core API with the body set to a JSON version of the contact to be added.

The API will return the created contact with the ID now filled in which will be returned to the caller. As I have said before catching the error and just writing it to the console isn’t the proper way to handle errors and this should be done in a different manner for a production application.

Contact detail view model

The view model that backs the contact detail view needed a function to allow saving of a contact. The following code uses the contact service to save a contact and then replace its local contact with the new one returned from the API. Finally, the class level variable indicating if the view model is in create or detail mode is set to true which triggers the UI to change out of create mode.

You will see in the sample code that a second function was added for  reset which is a quick way to reset the create UI.

Contact model

The constructor of the  contact class changed to make the data parameter optional to allow for the creation of an empty contact.

Include Angular Forms

For the two-way binding needed on the contact detail page Angular forms will be used. To include them in the project open the  app.module.ts file in the  ClientApp/app/ directory. Add the following import.

Then add  FormsModule to the  imports array.

Contact detail view

The following is the full contact view as it stands with all of the needed changes made. This will be followed by call outs of some of the important items.

All control of content rendering has been changed to use  hasContactId.

For the creation UI, the data is bound using Angular’s ngModel binding.

If you have any issues make sure and check that you have the  name attribute set to the property you are wanting to bind to.

The last thing to point out is the click handlers that are used to call the associate save and rest functions with the Save and Reset buttons are clicked.

Wrapping up

Now the application has the ability to add contact not just view them which is one step closer to what would be needed for a real application. The finished code can be found here.

Aurelia Contact Creation and Post to an API

Expanding on this post where a placeholder was added for contact creation the placeholder will be replaced with an actual UI. As part of the contact creation process, Aurelia’s fetch client will be used to make a post request to the ASP.NET API. The code at the starting point can be found here. If using the sample code keep in mind all the changes in this post takes place in the Aurelia project.

Contact service changes to allow post

In this project a service is used to keep all the Http bits isolated from the rest of the application. In the  contactService.ts file found in the  ClientApp/app/components/contacts/ directory a couple of changes need to be made. First the fetch import needs to expose json in addition to  HttpClient.

Then a  save function is added that makes a post request to the ASP.NET API and return a new contact based on the response from the post request. The contact in the post response will contain the ID assigned by the API.

Notice the usage of  json to serialize the contact being create to JSON before sending to the server. Also, note that just logging an error to the console isn’t a best practice and should be handling in a different way in a production application.

Contact detail view model

The view model that backs the contact detail view needed a function to allow saving of a contact. The following code uses the contact service to save a contact and then replace its local contact with the new one returned from the API. Finally, the class level variable indicating if the view model is in create or detail mode is set to true which triggers the UI to change out of create mode.

You will see in the sample code that a second function was added for  reset which is a quick way to reset the create UI.

Contact model

The constructor of the  contact class changed to make the data parameter optional to allow for the creation of an empty contact.

Contact detail view

The view under when the most changes and the following is the entirety of the UI file which can be found in the  contactDetail.html file. The code will be followed up with call outs for the important bits.

All control of content rendering has been changed to use  hasContactId.

For the creation UI, the data is bound using Aurelia’s value converters for more detail see the docs. The value converter is the  value.bind bit.

The last thing to point out is the click delegates that are used to call the associate save and rest functions with the Save and Reset buttons are clicked.

Wrapping up

The application now has the ability to add contact instead of only viewing existing contact which brings it close to a more realistic application. The code in its finished state can be found here.

The plan is to continue iterating on this application and moving the Aurelia and Angular 2 projects in parallel. I hope this is useful and if you have any specific features you would like to see implemented leave a comment.

Angular 2 Optional Route Parameter

This post expands on the Angular 2 post from a couple of weeks ago involving route links and parameters to include an “optional” route parameter. Using the use case from the same topic with Aurelia from last week’s post which is if a user ends up on the contact detail page with no contact ID they will be presented with the option to add a new contact. The starting point for the code can be found here. Keep in mind any changes in this post are taking place in the Angular project.

Route with an “optional” parameter

The reason for the quotes around optional is that with Angular’s current router I have found no way to make a route optional. As a work around two routes can be added that point to the same component. The following code is in the app.module.ts file of the ClientApp/app folder. The first handles calling the contact detail component without an ID and the second makes the call with an ID.

Contact detail changes

The contact detail view model found in the  contactdetail.component.ts file a class level property is needed to track of the contact detail component was called with an ID or not.

Next, in the  ngOnInit function has been changed to set the new property based on the route params having an ID set or not. If a contact ID is found then the details for that contact are loaded. The following is the full function.

In the associated view a placeholder for creating a new contact was added in the  contactdetail.component.html file. This placeholder was added just above the link back to the contact list. This placeholder will only show if the detail components are loaded with no ID.

Add create link to the contact list

To finish a “Create New Contact” link is added to the contact list view found in the  contactlist.component.html file which will call the contact detail component without a contact ID.

In the example solution, this link will show above the table of contacts.

Wrapping up

The finished code can be found here. If you have tried both Angular 2 and Aurelia leave a comment on how you think they compare and which you prefer.