Setting Up Visual Studio Code for Debugging ASP.NET Core

Visual Studio Code is a cross-platform source code editor from Microsoft. Out of the box, Code’s language support includes JavaScript, TypeScript, and Node. Using Codes extension system support is available for almost any language you want to use including C#, F#, Elixir, SQL, Swift, and Java. As of this writing, there are 734 language extensions available.

I have been using VS Code since it was first released after Build in 2015, but I have only been using it as an editor never taking advantage of the Debugging capabilities it has available. In this post, I am going to walk through everything that is needed to get a new ASP.NET Core with an Angular front end to run via VS Code’s debugger.

Test application

The first thing I did was to create a new application using JavaScriptServices specifically for this post. For instructions on how to use JavaScriptServices to generate an application check out this post.

On Windows, after the application has been generated and you are in the application directory you can use the following command to open the directory in VS Code.

I am sure there is something similar on Linux and Mac, but I don’t have the environments to try on.

VS Code Overview

When VS Code opens you will see a view close to the following.

The icons down the left side of the screen are for Explorer (shows currently open directory and files), Seach, Source Control (git support is built in), Debug, and Extensions.


The Debug tab will be our focus so click on it which will take you to the following view.

Using the gear with red circle select .NET Core as the environment for the project.

If you don’t see .NET Core listed click More… and click install for the C# option.

After selecting an environment VS Code will add a  launch.json file to the project. This file defines what happens when the start button is clicked in the debugger. At this point clicking the start button to run the application using the debugger will result in an error that  Could not find the preLaunchTask 'build'.

Next, click the Configure Task Runner option and select .NET Core.

This will add a task.json file with a build command that the launch.json is looking for. At this point, I had to restart VS Code to get it to properly pick up the new files. This seems to be an issue that will be fixed with the next release of VS Code and can be tracked using this issue.

After restart and trying to run the debugger again I ran into the error  Run 'Debug: Download .NET Core Debugger' in the Command Palette or open a .NET project directory to download the .NET Core Debugger.

I ended up having to uninstall and reinstall the C# extension and then opening a C# file to get the debugger to download. If you are having this problem make sure and open a C# file before going as far as reinstalling the C# extension.

Hitting run in the debugger now give the error  launch: launch.json must be configured. Change 'program' to the path to the executable file that you would like to debug.

To fix this issue click  Open launch.json and you will find two places with the following.

Change both places to point to the dll your application builds. In the case of my project named  DebugTest the final version ended up being the following.

Wrapping up

Debugging now works! Based on this post it would seem like debugging in VS Code is a big pain, but really after you get it set up once it just works. For new projects, you just have to let it add the

For new projects, you just have to let it add the launch.json and tasks.json and then set the path to your project’s assembly in launch.json. After that, you are ready to go.

I wait too long to figure this process out. I hope this helps you get started with debugging in VS Code.

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.

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.

Angular 2 – Router links, click handlers, routing parameters

As with last week’s post this post is going to cover multiple topics related to while creating a contact detail page to go along with the existing contact list page that is part of the ASP.NET Basics repo, but this time using Angular 2 instead of Aurelia. The code before any changes can be found here. If you are using the sample application keep in mind all the changes in this post take place in the Angular project.

Creating a detail view and view model

Create  contactdetail.component.html in  ClientApp\app\components\contacts. This view that will be used to display all the details of a specific contact. It will also link back to the contact list. The following image shows the folder structure after the view and view model have been added.


The following is the full contents of the view.

*ngIf is adding/removing the associated div based on a contact being set or not.

{{value}} is Angular’s one-way binding syntax. For more details check out the docs.

<a routerLink="/contact-list"> is using Angular to generate a link back to the contact list component.

View model

For the view model add  contactdetail.component.ts in the ClientApp\app\components\contacts folder which is the same folder used for the view.

Make not of the imports needed to make this view model work. To start off Contact is needed to define what the definition of a contact is and ContactService is being used to load the data for a specific contact.

Angular’s core is imported to allow the view model to set as a component using @Component decorator as well as to all implementation of OnInit lifecycle hook.  Angular’s router is being used in the  ngOnInit function to allow access the parameters of the route that caused the route to be triggered using  this.route.params.

The switchMap operator from reactive extensions is used to map the id from the route parameters to a new observable that has the result of this.contactService.getById.

Adding get by ID to the Contact Service

The existing  ContactService doesn’t provide a function to get a contact by a specific ID so one needs to be added.

The following calls the API in the Contacts project and uses the result to create an instance of a  Contact as a promise which is returned to the caller.

The base URL was also moved to a class level variable so that it could be shared.

Add a route with a parameter

To add the new contact detail to the list of routes that the application handles open  app.module.ts in the  ClientApp/app folder. First, add an import at the top of the file for the new component.

Next, add the  ContactDetailComponent to the  declarations array of the  @NgModule decorator.

Finally, add the new route to the  RouteModule in the  imports section of the  @NgModule decorator.

path is the pattern used to match URLs. In addition, parameters can be used in the form of :parameterName. The above route will handle requests for  http://baseurl/contact-detail/{id} where {id} is an ID of a contact. As demonstrated above in the ngOnInit function of the view model  route.params can be used to access route parameters.

component is used to locate the view/view model that goes with the route.

Integrating the detail view with the contact list

The contact list view and view model needed the following changes to support the contact detail page.

View model

A variable was added for the ID of the select contact was as well as a onSelect function which takes a contact and gets called when a contact is selected. The following is the fully contact list view model.

The changes to the view model were not required to add the contact detail page, but are used show how to set up a click handler the view side. In the future, the selected contact will come in handy when the list and details were shown at the same time.


The amount of data being displayed was reduced to just ID and name. A column was added with a link to the details page. The following is the full view.

(click)="onSelect(contact)" will cause the  onSelect function of the view model to be called with the related contact when the associated element is clicked.

[routerLink]="['/contact-detail',]" use the router to create a line to the contact details page passing the contact ID as a parameter.

As a reminder of how to use a route’s parameter here is the  ngOnInit function from the contact detail view model.

 Wrapping up

As with the related Aurelia post, there are a lot of topics covered in this post, but they are all related to the process of adding a new page and route to the application.

The code including all the changes for this post can be found here.


Angular 2 with an ASP.NET Core API

This week’s post is going to take the Angular 2 application from a couple of weeks ago and add the same functionality currently present in the Aurelia application found the ASP.NET Core Basic repo. This release is the starting point for the solution used in this post.

Starting point overview

When you download a copy of the repo you will find an ASP.NET Core solution that contains three projects. The Angular project is where this post will be focused.

The Contacts project has a set of razor views and a controller to go with them that support standard CRUD operations, which at the moment is the best way to get contact information in the database. It also contains the ContactsApiController which will be the controller used to feed contacts to the Angular 2 and Aurelia applications.

Multiple startup projects in Visual Studio

In order to properly test the functionality that will be covered here both the Contacts project and the Angular project will need to be running at the same time. Visual Studio provides a way to handle this. The Multiple startup projects in Visual Studio section of this post walks through the steps of setting up multiple startup project. The walk through is for the Aurelia project, but the same steps can be applied to the Angular project.


Create a contacts directory inside of  ClientApp/app/components/ of the Angular project. Next create a  contact.ts file to the  contacts directory. This file will be the model of a contact in the system. If you read the Aurelia version of this post you will noticed that this model is more fully defined since this project is using TypeScript the more fully defiled model provides more type safety. The following is the contests file.


To isolate HTTP access the application will use a service to encapsulate access to the ASP.NET Core API. For the service create a  contact.service.ts file in the  contacts directory of the Angular project. The following is the code for the service.

This class uses Angular’s HTTP client to access the API and download a list of contacts. Angular’s HTTP client uses reactive extensions and returns an observable. In this case we don’t need an observable so for this service the observable is being converted to a promise. Then from there the response from the API is being converted an array of type  contact.

Also make note of the  Injectable decorator which tells Angular 2 the class should be available for dependency injection.

View Model

The next step is to create a view model to support the view that will be used to display the contacts download from the API. Add a file named contactlist.component.ts to the contacts directory of the Angular project. The following is the full contents of the view model file. This will be followed by a breakdown of the file in order to highlight some parts of the file.

The import statements are pulling in a couple parts of the Angular 2 framework in addition to the contact model and contact service created above.

Next is a component decorator which marks the class as an Angular component and provides a method to set metadata about the class.

The selector property sets the identifier for the class to be used in templates. The  template property sets the view that should be used with the view model. In this case it is requiring in another file, but it could also contain the actual template that should be used to render the component. An alternate is to use templateUrl to point to an external file containing a template. The final property used in this example is the  providers  property which is a list of providers that the framework needs to be made available to the component, in this case the  ContractService. For more information on the component decorator check out the Angular docs.

The next thing of note on this class is that it implements  OnInit.

OnInit is one of Angular’s lifecycle hooks, see the docs for the rest of the available hooks.  OnInit is called once after component creation and runs the  ngOnInit function which in the case of this class is being used to get a list of contacts from the  ContactService.


For the view create a  contactlist.component.html in the  contacts directory of the Angular project. This is the file that the veiw model created above is bound with to display the contact data retrieved from the API. The following is the complete contents of the view file.

The second line repeats the li tag for each contact in the contacts array of the view model class.  {{expression}} is Angular’s syntax for one way data binding.  {{}} does a one way binding to the  name property of the current contact in the  *ngFor loop. For more details on the different options available for data binding see the docs.

Add menu

The final piece is to add an item to the menu from with the contact list can be accessed. Open  app.module.ts in the  ClientApp/app/components/ directory. Add an imports for the  ContactListComponent.

Next add a new path to the  RouterModule. The third from the bottom is the line that was added for the contact list.

Finally open the navmenu.component.html file in the ClientApp/app/components/navmenu/  directory. Add a new  li for the contact list matching the following.

Wrapping up

That is all it takes to consume some data from an ASP.NET Core API and use it in an Angular 2 application. I can’t stress enough how easy working with in the structure provided by JavaScriptServices helped in getting this project up and going quickly.

The completed code that goes along with this post can be found here. Also note that the Aurelia project has be redone as well also based on JavaScriptServices and TypeScript so that the applications will be easier to compare.

Angular 2 with ASP.NET Core using JavaScriptServices

This was going to be the fist in a series of posts covering getting started using the RTM versions of ASP.NET Core and Angular 2 together which was going to follow a similar path as the series on Aurelia and ASP.NET Core the first entry of which can be found here.

In the process of writing this post I was reminded of JavaScripServices (they recently added Aurelia support!) and will be using it to get this project up and running instead of doing the work manually.

The code found here can be used as a starting point. The repo contains a solutions with an ASP.NET Core API (Contacts) project and a MCV 6 (Aurelia) project. This post will be add a new MVC 6 project for Angular 2.

JavaScriptServices introduction

JavaScriptServices is an open source project by Microsoft for ASP.NET Core developers to quickly get up and running with one of many JavaScript front ends. The following is their own description.

JavaScriptServices is a set of technologies for ASP.NET Core developers. It provides infrastructure that you’ll find useful if you use Angular 2 / React / Knockout / etc. on the client, or if you build your client-side resources using Webpack, or otherwise want to execute JavaScript on the server at runtime.

The great thing about using the generator that JavaScriptServcies provides is they handle the integration between all the different tools which can be challenging to get right on your own without a lot of time and research.

Project creation

First step is to install the Yeomen generator via npm using the following command from a command prompt.

When installation is complete create a new directory call Angular for the project. In the context of the repo linked above this new directory would be in Contact/src at the same level as the Aurelia and Contacts folders.

Open a command prompt and navigate to the newly created directory and run the following command to kick off the generation process.

This will present you will a list of frameworks to choose from. We are going with Angular 2, but Aurelia, Knockout, React and React with Redux are also available.


Hit enter and it will ask for a project name which gets defaulted to the directory name so just hit enter again unless you want to use a different name. This kicks off the project creation which will take a couple of minutes to complete.

Add new project to existing solution

To include the new Angular project in an existing solution right click on the src folder in the Solution Explorer and select Add > Existing Project.


This shows the open file dialog. Navigate to the directory for the new Angular project and select the Angular project file.


Wrapping up

Set the Angular project as the start up project and hit run and you will find yourself in a fully functional Angular 2 application. It is amazing how simple JavaScriptServices makes getting started with a new project.

The tool setup seems to be one of the biggest pain points with any SPA type JavaScript framework. Aurelia is a little friendlier to ASP.NET Core out of the box than Angular 2, but it still isn’t the simplest process ever. JavaScriptServices is one of those thing I wish I had tried out sooner.

In the near future I am going to redo the Aurelia project in this solution using JavaScriptServices. From there I will come back to the Angular project created in this post and integrate it with the Contact API used in the existing Aurelia application.

Completed code for this post can be found here.

Angular 2 Template Driven Validation

Last week’s post covered model driven validation in Angular 2 and this week I will be looking at template driven validation. Template driven validation provides a simplified way to add validation without the need to directly use a control group. This is a great way to get up and running for simple form cases, and maybe more complex ones as well. I haven’t hit a case yet that wouldn’t work with either validation style.

Building a Template Form with Validation

I started with a simple form that contains labels and inputs for entering a name and email address that are bound to corresponding values in the associated model.

The next example is the same form with validation added.

The first change you will notice is that the form now has a name assigned using  #contactForm="ngForm". In this case the name is not used, but it could be used to disable a submit button if any of the inputs the form contained didn’t have valid values. I am sure there are a lot more use cases as well.

On the inputs that need validation a controls name is assigned via  ngControl="name" and a name is assigned using  #nameControl="ngForm". I had some trouble withe assigning names to my inputs at first I keep getting the following.

The cause of the issue was that I was trying to use  #name for the control name which was already a property on the model. Once I changed to  #nameControl all worked fine.

For the input for name above  required minlength="3" tells the Angular form that the input is required and must be at least three characters in length.

Displaying Validation

For the name input you can see that it has two divs used to show specific messages based on which validation condition failed.

I am not sure why, but when using the template style validation I had to check  !nameControl.errors in addition to the specific error like  !nameControl.errors.required or I would get an exception when the page tried to load. If your control doesn’t have more than a single validation then  nameControl.valid would be a sufficient condition for showing validation messages.

Custom Validators

I am going to use the same email validator from last week with a few changes so can be used from a template. The following is the full class.

The biggest difference is the  @Directive decorator. The selector is the attribute that will be used to mark that an input needs to pass the specified validation. I am not 100% sure of the specifics of the provider, but the above works. This is another topic I need to explore more.

Using a Custom Validator

First in the model the validator must be imported.

Then the validator needs to be added to the directives section of the @Component decorator.

To use in the view just add the emailValidator selector to the proper input.

Finally add a div to display the error.

Wrapping Up

Using template driven validation you can quickly get a form validated without having to make changes outside of your template (unless you are using a custom validator). Angular 2 offers a lot of options when it comes to validation and where it should be put.

Angular 2 Model Driven Validation

In this post a couple of weeks ago I covered Aurelia’s new validation plugin and I thought it would be good to see what Angular 2 has to offer validation wise. Angular’s offering is vastly different that Aurelia. Angular can use model driven or template driven validations. This post is going to look at the model driven style.


Angular forms is the framework’s way to handle groups of data entry that need support for data binding and validation among other things.

Building a Form with Validation

The first step to building a model driven form is import the classes that will be needed.

Next add a variable for control group and setup the control group in the constructor of the class.

The above uses FormBuilder to define a name property that is required with a minimum length of three characters and an email property that is required. Later in the post I will add better email validation via customer validator.

Angular 2 only comes with required, minimum length, max length and pattern (match given regex) validators out of the box. Thankfully custom validators are pretty easy to implement.

Using a From with a View

Now that the form is setup the view needs to utilize it. The following is the code form the view.

First notice in the form tag  [ngFormModel]="contactForm" is used to bind the form to the control group crated in the model.

Instead of  [(ngModel)]="name" we use  ngControl="name" to bind the input box to the name control in the control group that was crated using the form builder above.  #name="ngForm" defines  name as a variable that can be used later.

<div [hidden]="name.valid || name.pristine || !name.errors.required">Required</div>  is used to display validation errors to the user. This code is just saying to hide the div if name is valid or pristine (not changed by the user)  or if the validation error is not because the field is required. While this style works I much prefer Aurelia as it handles the extra work needed to automatically display validation errors.

Custom Validators

As I mention above I am going to show you a custom validator that can be used to better handle email validation. Most of this validation I found in a search but unfortunately I forgot to save the URL so I can’t link to the exact source. The following is the complete code for a custom email validator.

Note that returning null means that validation passed.

Using a Custom Validator in a Model

First the custom validator needs to be imported.

Now the validator can be used in the classes form builder.

Notices that the email control is now using  Validators.compose which is used to apply multiple validations to a single control.

Using a Custom Validator in a View

Now the view just has to be changed to show the user that the reason for the failed validation is an invalid email address.

Note that the entry in errors will match the return value from the custom validator. I had issues trying to use the minimum length validator because I was trying to use  minLength instead of  minlength. If you are having trouble with validation message showing up that would be the first thing to check.

Wrapping Up

That covers the basics of model driven validation in Angular 2. Be on the look out for a post in the future that covers the same concepts but using a template driven approach. I also wanted to point out this post by Pascal Precht and this post by David Den Toom which helped me a lot in writing this post.

Migration from Angular 2 Betas to RC

On May 2nd Angular 2 moved from the beta stage to the release candidate stage and is currently on RC 1. The move from beta to RC was a bit more involved than the moves between beta. This post is going to cover the changes I went through to get my SPA sample application migrated to RC 1.

Update package.json

With this release Angular 2 was split from a single dependency in to multiple. The other big change is a rename of from angular2  to @angular. The following is my updated dependencies section.

After the above change make sure to run  npm install in the root of the project from a command prompt. Not sure if it was just me, but the dependency auto restore in Visual Studio wouldn’t work for the @angular dependencies.

Update gulpfile.js

Due to the changes in the dependency structure my gulpfile had to be updated to copy the new files to the proper locations. I took the opportunity to move all of my dependency to a lib folder.

If you were using the previous version of my gulp take make sure to remove the old dependencies from the wwwroot/Angular/ folder.

Update Entry Point View

Again because of the dependency changes the entry point view for the Angular 2 application needed changes which is Angular2.cshtml in my project. A systemjs.config.js was added to handle the bulk of the configuration. The following is the full source for my entry point view.

Add system.config.js

This new file is where the configuration of systemjs happens. I found this setup in Dan Wahlin’s Angular2-JumpStart project which can be found here. The only real changes I made from Dan’s file was to adjust the map section to match my folder layout.

Update Component Imports

With the change in package names all imports that were using  angular2 need to be changed to  @angular. The following is an example of this from my app.component.ts file.

NgFor Change

There was also a slight syntax change around  ngFor that changes the name declaration of the current item in the iteration of a loop. The following shows the before and after.


With the above changes my application was run able again. The hardest part of the upgrade for me was getting systemjs configured properly. Hope your upgrade goes smooth and if not leave a comment with what issues you had.

Custom Pipes in Angular 2

I am working on a project that is using an ASP.NET Core web API to return JSON that is then used by Angular 2. The dates that needed to be formatted before being shown to the user which lead me to pipes.


In Angular 2 pipes are away to apply some transformation on a field before its value is displayed to the user. Some common pipes are provided out of the box for things like numbers, dates and percentages.

For the following example created  is a property for the date a contact was added. To have created just display the month, date and year the date pipe will be used with the short date format.

The above is standard Angular 2 binding  with an added pipe “|” followed by the name of the pipe which in this case is date. The built-in date pipe can take arguments for how to the date should be formatted. If the created date was today than the resulting output of the above binding would be 4/10/2016. For a full list of built-in formats see the Angular docs.

The Problem

I added the date pipe to the fields that needed formatting and ran the app. Instead of the formatted date I was expecting I got a partially rendered page. A quick peek in Chrome’s dev tools showed the following exception.

EXCEPTION: Invalid argument ‘2016-04-10T08:00:00’ for pipe ‘DatePipe’ in [{{contact.created | date: ‘shortDate’}}

Turns out that the date pipe only works if the value it is processing is a number or a date. I found this out by looking at the code for the date pipe which can be found here. My created property came from JSON which doesn’t have a way to denote something as a date. This means the created property is actually a string instead of a date..

Solution 1 – Convert to a date

One way to fix this issue is to use the string representation of the date to create a new date and assign it over the top of the existing property. For example:

After the above is applied to all the dates that need formatted Angular’s date pipe can be used with no problems.

Solution 2 – Custom pipe

I decided to try writing a custom pipe that would take a string that should be a date and format it if it is actually date using Angular’s date pipe.  The following is the resulting pipe.

First  Pipe and  PipeTransform are imported. The class must be decorated with  @Pipe which is also used to give the pipe its name. The class must also implement  PipeTransform which defines a  transform function.

The  transform function is where all the work happens. It takes a value and formatting arguments and return the value that should be displayed. In my case the value is parsed to a date which returns the number of milliseconds since January 1, 1970 00:00:00 UTC or not a number if parsing fails for some reason. For the not a number result an empty string will be return and displayed to the user.

In the case the date is value then a new instance of Angular’s date pipe is created it handles formatting using the new date value which is then return and displayed for the user. In order to use Angular’s date pipe inside my custom pipe it needed to be imported as well.

Custom Pipe Usage

To use a custom pipe it must be imported by the view model class of the view that needs formatted.

Then it must be added to the component decorator.

The view will now be able to use the pipe. The syntax is the same as built-in pipes just with the name provided in the pipe decorator which is dateString in this example.


The above are two of the solutions I came up with when I had problems with Angular’s built in date pipe. They are by no means the only options. If you have a suggestion on a better way to handle dates coming from JSON please leave a comment.

Also note that there is an issue logged on the Angular repo to support strings in the built in date pipe which can be found here.