Angular 6 Application With Cosmos DB And Web API 2

In this article, we will create an Angular 6 application with Web API 2.0. We will see all four CRUD operations and save the data to Cosmos DB. For testing purpose, we can use Cosmos DB emulator and save the data to local system. After successfully completed testing, we can create a Cosmos DB service in Azure also.

In this article, we will create an Angular 6 application with Web API 2.0. We will see all four CRUD operations and save the data to Cosmos DB. For testing purpose, we can use Cosmos DB emulator and save the data to the local system. After successfully completing testing, we can create a Cosmos DB service in Azure also.

For those who are new to Cosmos DB,
Azure Cosmos DB is Microsoft's globally distributed, multi-model database. With the click of a button, Azure Cosmos DB enables you to elastically and independently scale throughput and storage across any number of Azure's geographic regions. It offers throughput, latency, availability, and consistency guarantees with comprehensive service level agreements (SLAs), something no other database service can offer. Currently, there are five different types of APIs are supported by Cosmos DB as given below.
  • SQL
  • MongoDB
  • Graph
  • Table
  • Cassandra
Web API Service creation

Create a new Web API 2.0 project
WebAPI4AngularCosmosDB using Visual Studio.

Angular 6 Application with Cosmos DB and Web API 2

I am using
ASP.NET 4.5 Templates for it.

Angular 6 Application with Cosmos DB and Web API 2  

In the next step, we are going to install Microsoft.Azure.DocumentDBNuGet package.

Angular 6 Application with Cosmos DB and Web API 2  
We can create a DocumentDBRepositoryclass now. This is the core repository for CosmosDB CRUD operations,

DocumentDBRepository.cs
 
  1. namespace WebAPI4AngularCosmosDB  
  2. {  
  3.     using System;  
  4.     using System.Collections.Generic;  
  5.     using System.Configuration;  
  6.     using System.Linq;  
  7.     using System.Linq.Expressions;  
  8.     using System.Threading.Tasks;  
  9.     using Microsoft.Azure.Documents;  
  10.     using Microsoft.Azure.Documents.Client;  
  11.     using Microsoft.Azure.Documents.Linq;  
  12.     public static class DocumentDBRepository<T> where T : class  
  13.     {  
  14.         private static readonly string DatabaseId = ConfigurationManager.AppSettings["database"];  
  15.         private static readonly string CollectionId = ConfigurationManager.AppSettings["collection"];  
  16.         private static DocumentClient client;  
  17.   
  18.         public static async Task<T> GetItemAsync(string id)  
  19.         {  
  20.             try  
  21.             {  
  22.                 Document document = await client.ReadDocumentAsync(UriFactory.CreateDocumentUri(DatabaseId, CollectionId, id));  
  23.                 return (T)(dynamic)document;  
  24.             }  
  25.             catch (DocumentClientException e)  
  26.             {  
  27.                 if (e.StatusCode == System.Net.HttpStatusCode.NotFound)  
  28.                 {  
  29.                     return null;  
  30.                 }  
  31.                 else  
  32.                 {  
  33.                     throw;  
  34.                 }  
  35.             }  
  36.         }  
  37.   
  38.         public static async Task<IEnumerable<T>> GetItemsAsync()  
  39.         {  
  40.             IDocumentQuery<T> query = client.CreateDocumentQuery<T>(  
  41.                 UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId),  
  42.                 new FeedOptions { MaxItemCount = -1 })  
  43.                 .AsDocumentQuery();  
  44.   
  45.             List<T> results = new List<T>();  
  46.             while (query.HasMoreResults)  
  47.             {  
  48.                 results.AddRange(await query.ExecuteNextAsync<T>());  
  49.             }  
  50.   
  51.             return results;  
  52.         }  
  53.   
  54.         public static async Task<IEnumerable<T>> GetItemsAsync(Expression<Func<T, bool>> predicate)  
  55.         {  
  56.             IDocumentQuery<T> query = client.CreateDocumentQuery<T>(  
  57.                 UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId),  
  58.                 new FeedOptions { MaxItemCount = -1 })  
  59.                 .Where(predicate)  
  60.                 .AsDocumentQuery();  
  61.   
  62.             List<T> results = new List<T>();  
  63.             while (query.HasMoreResults)  
  64.             {  
  65.                 results.AddRange(await query.ExecuteNextAsync<T>());  
  66.             }  
  67.   
  68.             return results;  
  69.         }  
  70.   
  71.         public static async Task<T> GetSingleItemAsync(Expression<Func<T, bool>> predicate)  
  72.         {  
  73.             IDocumentQuery<T> query = client.CreateDocumentQuery<T>(  
  74.                 UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId),  
  75.                 new FeedOptions { MaxItemCount = -1 })  
  76.                 .Where(predicate)  
  77.                 .AsDocumentQuery();  
  78.             List<T> results = new List<T>();  
  79.             results.AddRange(await query.ExecuteNextAsync<T>());  
  80.             return results.SingleOrDefault();  
  81.         }  
  82.   
  83.         public static async Task<Document> CreateItemAsync(T item)  
  84.         {  
  85.             return await client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId), item);  
  86.         }  
  87.   
  88.         public static async Task<Document> UpdateItemAsync(string id, T item)  
  89.         {  
  90.             return await client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(DatabaseId, CollectionId, id), item);  
  91.         }  
  92.   
  93.         public static async Task DeleteItemAsync(string id)  
  94.         {  
  95.             await client.DeleteDocumentAsync(UriFactory.CreateDocumentUri(DatabaseId, CollectionId, id));  
  96.         }  
  97.   
  98.         public static void Initialize()  
  99.         {  
  100.             client = new DocumentClient(new Uri(ConfigurationManager.AppSettings["endpoint"]), ConfigurationManager.AppSettings["authKey"]);  
  101.             CreateDatabaseIfNotExistsAsync().Wait();  
  102.             CreateCollectionIfNotExistsAsync().Wait();  
  103.         }  
  104.   
  105.         private static async Task CreateDatabaseIfNotExistsAsync()  
  106.         {  
  107.             try  
  108.             {  
  109.                 await client.ReadDatabaseAsync(UriFactory.CreateDatabaseUri(DatabaseId));  
  110.             }  
  111.             catch (DocumentClientException e)  
  112.             {  
  113.                 if (e.StatusCode == System.Net.HttpStatusCode.NotFound)  
  114.                 {  
  115.                     await client.CreateDatabaseAsync(new Database { Id = DatabaseId });  
  116.                 }  
  117.                 else  
  118.                 {  
  119.                     throw;  
  120.                 }  
  121.             }  
  122.         }  
  123.   
  124.         private static async Task CreateCollectionIfNotExistsAsync()  
  125.         {  
  126.             try  
  127.             {  
  128.                 await client.ReadDocumentCollectionAsync(UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId));  
  129.             }  
  130.             catch (DocumentClientException e)  
  131.             {  
  132.                 if (e.StatusCode == System.Net.HttpStatusCode.NotFound)  
  133.                 {  
  134.                     await client.CreateDocumentCollectionAsync(  
  135.                         UriFactory.CreateDatabaseUri(DatabaseId),  
  136.                         new DocumentCollection { Id = CollectionId },  
  137.                         new RequestOptions { OfferThroughput = 1000 });  
  138.                 }  
  139.                 else  
  140.                 {  
  141.                     throw;  
  142.                 }  
  143.             }  
  144.         }  
  145.     }  
  146. }  

This is a static and generic class. Inside this class, we have anInitialize method and it will be invoked from the Application_Start method inside Global.asax class.

Angular 6 Application with Cosmos DB and Web API 2  
 
When the application starts, DocumentDBRepository<Hero>.Initialize() will be called and it will create one Cosmos DB database and collection if it does not exist. Please note that in the first run, there was no database and collection in our Cosmos DB.

Cosmos DB
endpoint, key, database and collection name must be stored in the Web.config file.
  1. <configuration>  
  2.   <appSettings>  
  3.     <add key="webpages:Version" value="3.0.0.0" />  
  4.     <add key="webpages:Enabled" value="false" />  
  5.     <add key="ClientValidationEnabled" value="true" />  
  6.     <add key="UnobtrusiveJavaScriptEnabled" value="true" />  
  7.     <add key="endpoint" value="https://localhost:8081" />  
  8.     <add key="authKey" value="C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==" />  
  9.     <add key="database" value="AngularHeroDB" />  
  10.     <add key="collection" value="MyCollection1" />  
  11.   </appSettings>  
  12. ...........

Please note that in this application we are using Cosmos DB local emulator instead of real Azure Cosmos DB service. This is for testing purposes. Once our testing is over, we will change this configuration with real Cosmos DB configurations.

You can get the Cosmos DB local emulator from below URL.
Download the emulator and install it on your local system. After successful installation, you can run the emulator and it will show as a service in your system tray.

Angular 6 Application with Cosmos DB and Web API 2  

If you click the 
Open Data Explorer, a local Cosmos DB emulator will be opened in your browser.

Angular 6 Application with Cosmos DB and Web API 2  

In 
the Explorer button, you can see currently there is no database available in our emulator.

Angular 6 Application with Cosmos DB and Web API 2  

Now, we are 
going to create a model Hero.cs in our Web API project inside the Models folder.
  1. namespace WebAPI4AngularCosmosDB.Models  
  2. {  
  3.     using Newtonsoft.Json;  
  4.     public class Hero  
  5.     {  
  6.         [JsonProperty(PropertyName = "id")]  
  7.         public string Id { getset; }  
  8.         [JsonProperty(PropertyName = "uid")]  
  9.         public string UId { getset; }  
  10.         [JsonProperty(PropertyName = "name")]  
  11.         public string Name { getset; }  
  12.         [JsonProperty(PropertyName = "saying")]  
  13.         public string Saying { getset; }  
  14.     }  
  15. }  

Please note we used JsonProperty attribute in this class so that we can convert our csharpproperty to json property easily.

Now we are going to invoke DocumentDBRepositoryclass fromApplication_Start method inside Global.asax through dependency injection.

Global.asax
  1. namespace WebAPI4AngularCosmosDB  
  2. {  
  3.     using System.Web.Http;  
  4.     using System.Web.Mvc;  
  5.     using System.Web.Optimization;  
  6.     using System.Web.Routing;  
  7.     using WebAPI4AngularCosmosDB.Models;  
  8.   
  9.     public class WebApiApplication : System.Web.HttpApplication  
  10.     {  
  11.         protected void Application_Start()  
  12.         {  
  13.             AreaRegistration.RegisterAllAreas();  
  14.             GlobalConfiguration.Configure(WebApiConfig.Register);  
  15.             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);  
  16.             RouteConfig.RegisterRoutes(RouteTable.Routes);  
  17.             BundleConfig.RegisterBundles(BundleTable.Bundles);  
  18.   
  19.             DocumentDBRepository<Hero>.Initialize();  
  20.         }  
  21.     }  
  22. }  

Please build the application and run it with your local IIS server.

DocumentDBRepository<Hero>.Initialize() will execute the Initialize method and the below two asynchronized methods also will be executed.

CreateDatabaseIfNotExistsAsync().Wait();
CreateCollectionIfNotExistsAsync().Wait();

If you check the Cosmos DB emulator data explorer, you can see that our new database and collection is created successfully.
 
Angular 6 Application with Cosmos DB and Web API 2  

In our Web.config configurations, we give database as AngularHeroDB and collection as MyCollection1.

We can create ourHeroController.cs API controller and create all four CRUD methods. All these methods are very simple. Through these methods we can create, edit, update and delete the hero which we use in our Angular application.

HeroController.cs
  1. namespace WebAPI4AngularCosmosDB.Controllers  
  2. {  
  3.     using WebAPI4AngularCosmosDB.Models;  
  4.     using System;  
  5.     using System.Collections.Generic;  
  6.     using System.Threading.Tasks;  
  7.     using System.Web.Http;  
  8.   
  9.     [RoutePrefix("api/Hero")]  
  10.     public class HeroController : ApiController  
  11.     {  
  12.   
  13.         [HttpGet]  
  14.         public async Task<IEnumerable<Hero>> GetAsync()  
  15.         {  
  16.   
  17.             IEnumerable<Hero> value = await DocumentDBRepository<Hero>.GetItemsAsync();  
  18.             return value;  
  19.         }  
  20.   
  21.         [HttpPost]  
  22.         public async Task<Hero> CreateAsync([FromBody] Hero hero)  
  23.         {  
  24.             if (ModelState.IsValid)  
  25.             {  
  26.                 await DocumentDBRepository<Hero>.CreateItemAsync(hero);  
  27.                 return hero;  
  28.             }  
  29.             return null;  
  30.         }  
  31.         public async Task<string> Delete(string uid)  
  32.         {  
  33.             try  
  34.             {  
  35.                 Hero item = await DocumentDBRepository<Hero>.GetSingleItemAsync(d => d.UId == uid);  
  36.                 if (item == null)  
  37.                 {  
  38.                     return "Failed";  
  39.                 }  
  40.                 await DocumentDBRepository<Hero>.DeleteItemAsync(item.Id);  
  41.                 return "Success";  
  42.             }  
  43.             catch (Exception ex)  
  44.             {  
  45.                 return ex.ToString();  
  46.             }  
  47.         }  
  48.         public async Task<Hero> Put(string uid, [FromBody] Hero hero)  
  49.         {  
  50.             try  
  51.             {  
  52.                 if (ModelState.IsValid)  
  53.                 {  
  54.                     Hero item = await DocumentDBRepository<Hero>.GetSingleItemAsync(d => d.UId == uid);  
  55.                     if (item == null)  
  56.                     {  
  57.                         return null;  
  58.                     }  
  59.                     hero.Id = item.Id;  
  60.                     await DocumentDBRepository<Hero>.UpdateItemAsync(item.Id, hero);  
  61.                     return hero;  
  62.                 }  
  63.                 return null; ;  
  64.             }  
  65.             catch (Exception ex)  
  66.             {  
  67.                 return null;  
  68.             }  
  69.   
  70.         }  
  71.   
  72.   
  73.     }  
  74. }  

If needed you can check our API methods from POSTMAN or any other REST client.

Angular Application creation.

Create a new Angular application using Angular CLI

ng new Angular4WebAPICosmosDB

It will take some time to create a new project and after successful creation open the application in any code editor. I am using Visual Studio code as IDE.

Please note that in this Angular application, we are using styles.scss file instead of default style.css file. You must change the build settings for styles in the angular.json file.

Angular 6 Application with Cosmos DB and Web API 2  
style.scss
  1. * {  
  2.     font-familyArial;  
  3.   }  
  4.   h2 {  
  5.     color#444;  
  6.     font-weightlighter;  
  7.   }  
  8.   body {  
  9.     margin2em;  
  10.   }  
  11.     
  12.   body,  
  13.   input[text],  
  14.   button {  
  15.     color#888;  
  16.     // font-family: Cambria, Georgia;  
  17.   }  
  18.   button {  
  19.     font-size14px;  
  20.     font-familyArial;  
  21.     background-color#eee;  
  22.     bordernone;  
  23.     padding5px 10px;  
  24.     border-radius: 4px;  
  25.     cursorpointer;  
  26.     cursor: hand;  
  27.     &:hover {  
  28.       background-color#cfd8dc;  
  29.     }  
  30.     &.delete-button {  
  31.       floatright;  
  32.       background-colorgray !important;  
  33.       background-colorrgb(216591!important;  
  34.       colorwhite;  
  35.       padding4px;  
  36.       positionrelative;  
  37.       font-size12px;  
  38.     }  
  39.   }  
  40.   div {  
  41.     margin: .1em;  
  42.   }  
  43.     
  44.   .selected {  
  45.     background-color#cfd8dc !important;  
  46.     background-colorrgb(0120215!important;  
  47.     colorwhite;  
  48.   }  
  49.     
  50.   .heroes {  
  51.     floatleft;  
  52.     margin0 0 2em 0;  
  53.     list-style-typenone;  
  54.     padding0;  
  55.     li {  
  56.       cursorpointer;  
  57.       positionrelative;  
  58.       left: 0;  
  59.       background-color#eee;  
  60.       margin: .5em;  
  61.       padding: .5em;  
  62.       height3.0em;  
  63.       border-radius: 4px;  
  64.       width17em;  
  65.       &:hover {  
  66.         color#607d8b;  
  67.         colorrgb(0120215);  
  68.         background-color#ddd;  
  69.         left: .1em;  
  70.       }  
  71.       &.selected:hover {  
  72.         /*background-color: #BBD8DC !important;*/  
  73.         colorwhite;  
  74.       }  
  75.     }  
  76.     .text {  
  77.       positionrelative;  
  78.       top: -3px;  
  79.     }  
  80.     .saying {  
  81.       margin5px 0;  
  82.     }  
  83.     .name {  
  84.       font-weightbold;  
  85.     }  
  86.     .badge {  
  87.       /* display: inline-block; */  
  88.       floatleft;  
  89.       font-sizesmall;  
  90.       colorwhite;  
  91.       padding0.7em 0.7em 0 0.5em;  
  92.       background-color#607d8b;  
  93.       background-colorrgb(0120215);  
  94.       background-color:rgb(134183221);  
  95.       line-height1em;  
  96.       positionrelative;  
  97.       left: -1px;  
  98.       top: -4px;  
  99.       height3.0em;  
  100.       margin-right: .8em;  
  101.       border-radius: 4px 0 0 4px;  
  102.       width1.2em;  
  103.     }  
  104.   }  
  105.     
  106.   .header-bar {  
  107.     background-colorrgb(0120215);  
  108.     height4px;  
  109.     margin-top10px;  
  110.     margin-bottom10px;  
  111.   }  
  112.     
  113.   label {  
  114.     display: inline-block;  
  115.     width4em;  
  116.     margin: .5em 0;  
  117.     color#888;  
  118.     &.value {  
  119.       margin-left10px;  
  120.       font-size14px;  
  121.     }  
  122.   }  
  123.     
  124.   input {  
  125.     height2em;  
  126.     font-size1em;  
  127.     padding-left: .4em;  
  128.     &::placeholder {  
  129.         color: lightgray;  
  130.         font-weightnormal;  
  131.         font-size12px;  
  132.         letter-spacing3px;  
  133.     }  
  134.   }  
  135.     
  136.   .editarea {  
  137.     floatleft;  
  138.     input {  
  139.       margin4px;  
  140.       height20px;  
  141.       colorrgb(0120215);  
  142.     }  
  143.     button {  
  144.       margin8px;  
  145.     }  
  146.     .editfields {  
  147.       margin-left12px;  
  148.     }  
  149.   }  
  150.     

Please modify the existingapp.component.ts file with the below changes.

app.component.ts
  1. import { Component } from '@angular/core';  
  2.   
  3. @Component({  
  4.   selector: 'app-root',  
  5.   template: `  
  6.     <h1>  
  7.       Angular Heroes with Cosmos DB  
  8.     </h1>  
  9.     <div class="header-bar"></div>  
  10.     <app-heroes></app-heroes>  
  11.   `  
  12. })  
  13. export class AppComponent {}  

Please add the below model file hero.ts. This is the model file for our type hero,

hero.ts
  1. export class Hero {  
  2.     uid: string;  
  3.     name: string;  
  4.     saying: string;  
  5. }  

Please addhero.service.ts

This service is used for handling the CRUD operations.

hero.service.ts
  1. import { Injectable } from '@angular/core';  
  2. import { HttpClient } from '@angular/common/http';  
  3.   
  4. import { Hero } from './hero';  
  5.   
  6. const api = 'http://localhost:1947/api';  
  7.   
  8. @Injectable()  
  9. export class HeroService {  
  10.   constructor(private http: HttpClient) { }  
  11.   
  12.   getHeroes() {  
  13.     return this.http.get<Array<Hero>>(`${api}/hero`);  
  14.   }  
  15.   
  16.   deleteHero(hero: Hero) {  
  17.     return this.http.delete(`${api}/hero?uid=${hero.uid}`);  
  18.   }  
  19.   
  20.   addHero(hero: Hero) {  
  21.     return this.http.post<Hero>(`${api}/hero/`, hero);  
  22.   }  
  23.   
  24.   updateHero(hero: Hero) {  
  25.     return this.http.put<Hero>(`${api}/hero?uid=${hero.uid}`, hero);  
  26.   }  
  27. }  

Add heroes.component.ts

This is the component file which controls the entire view,

heroes.component.ts
  1. import { Component, OnInit } from '@angular/core';  
  2.   
  3. import { Hero } from './hero';  
  4. import { HeroService } from './hero.service';  
  5.   
  6. @Component({  
  7.   selector: 'app-heroes',  
  8.   templateUrl: './heroes.component.html'  
  9. })  
  10. export class HeroesComponent implements OnInit {  
  11.   addingHero = false;  
  12.   deleteButtonSelected = false;  
  13.   heroes: any = [];  
  14.   selectedHero: Hero;  
  15.   
  16.   constructor(private heroService: HeroService) { }  
  17.   
  18.   ngOnInit() {  
  19.     this.getHeroes();  
  20.   }  
  21.   
  22.   cancel() {  
  23.     this.addingHero = false;  
  24.     this.selectedHero = null;  
  25.   }  
  26.   
  27.   deleteHero(hero: Hero) {  
  28.     this.deleteButtonSelected = true;  
  29.     let value: boolean;  
  30.     value = confirm("Are you sure want to delete this hero?");  
  31.     if (value != true) {  
  32.       return;  
  33.     }  
  34.     this.heroService.deleteHero(hero).subscribe(res => {  
  35.       this.heroes = this.heroes.filter(h => h !== hero);  
  36.       if (this.selectedHero === hero) {  
  37.         this.selectedHero = null;  
  38.       }  
  39.     });  
  40.   }  
  41.   
  42.   getHeroes() {  
  43.     return this.heroService.getHeroes().subscribe(heroes => {  
  44.       this.heroes = heroes;  
  45.     });  
  46.   }  
  47.   
  48.   enableAddMode() {  
  49.     this.addingHero = true;  
  50.     this.selectedHero = new Hero();  
  51.   }  
  52.   
  53.   onSelect(hero: Hero) {  
  54.     if (this.deleteButtonSelected == false) {  
  55.       this.addingHero = false;  
  56.       this.selectedHero = hero;  
  57.     }  
  58.     this.deleteButtonSelected = false;  
  59.   }  
  60.   
  61.   save() {  
  62.     if (this.addingHero) {  
  63.       this.heroService.addHero(this.selectedHero).subscribe(hero => {  
  64.         this.addingHero = false;  
  65.         this.selectedHero = null;  
  66.         this.heroes.push(hero);  
  67.       });  
  68.     } else {  
  69.       this.heroService.updateHero(this.selectedHero).subscribe(hero => {  
  70.         this.addingHero = false;  
  71.         this.selectedHero = null;  
  72.       });  
  73.     }  
  74.   }  
  75. }  

Now we can add our view, heroes.component.html

heroes.component.html
  1. <div>  
  2.     <ul class="heroes">  
  3.         <li *ngFor="let hero of heroes" (click)="onSelect(hero)" [class.selected]="hero === selectedHero">  
  4.             <button class="delete-button" (click)="deleteHero(hero)">Delete</button>  
  5.             <div class="hero-element">  
  6.                 <div class="badge">{{hero.uid}}</div>  
  7.                 <div class="name">{{hero.name}}</div>  
  8.                 <div class="saying">{{hero.saying}}</div>  
  9.             </div>  
  10.         </li>  
  11.     </ul>  
  12.     <div class="editarea">  
  13.         <button (click)="enableAddMode()">Add New Hero</button>  
  14.         <div *ngIf="selectedHero">  
  15.             <div class="editfields">  
  16.                 <div>  
  17.                     <label>id: </label>  
  18.                     <input [(ngModel)]="selectedHero.uid" placeholder="id" *ngIf="addingHero" />  
  19.                     <label *ngIf="!addingHero" class="value">{{selectedHero.uid}}</label>  
  20.                 </div>  
  21.                 <div>  
  22.                     <label>name: </label>  
  23.                     <input [(ngModel)]="selectedHero.name" placeholder="name" />  
  24.                 </div>  
  25.                 <div>  
  26.                     <label>saying: </label>  
  27.                     <input [(ngModel)]="selectedHero.saying" placeholder="saying" />  
  28.                 </div>  
  29.             </div>  
  30.             <button (click)="cancel()">Cancel</button>  
  31.             <button (click)="save()">Save</button>  
  32.         </div>  
  33.     </div>  
  34. </div>  

Finally add new file references to app.module.ts file.

app.module.ts
  1. import { BrowserModule } from '@angular/platform-browser';  
  2. import { NgModule } from '@angular/core';  
  3. import { FormsModule } from '@angular/forms';  
  4. import { HttpClientModule } from '@angular/common/http';  
  5.   
  6. import { AppComponent } from './app.component';  
  7. import { HeroService } from './hero.service';  
  8. import { HeroesComponent } from './heroes.component';  
  9.   
  10. @NgModule({  
  11.   declarations: [  
  12.     AppComponent,  
  13.     HeroesComponent  
  14.   ],  
  15.   imports: [  
  16.     BrowserModule,  
  17.     FormsModule,  
  18.     HttpClientModule  
  19.   ],  
  20.   providers: [HeroService],  
  21.   bootstrap: [AppComponent]  
  22. })  
  23. export class AppModule { }  

Before running our Angular application, we need to enable CORS in our Web API to allow requests from Angular application. For that, installMicrosoft.AspNet.WebApi.Cors using NuGet

Angular 6 Application with Cosmos DB and Web API 2  
 
Now add the below code inside the Register method in WebApiConfig.csfile.
  1. namespace WebAPI4AngularCosmosDB  
  2. {  
  3.     using System.Web.Http;  
  4.     using System.Web.Http.Cors;  
  5.   
  6.     public static class WebApiConfig  
  7.     {  
  8.         public static void Register(HttpConfiguration config)  
  9.         {  
  10.             config.MapHttpAttributeRoutes();  
  11.   
  12.             EnableCorsAttribute cors = new EnableCorsAttribute("*""*""*");  
  13.             config.EnableCors(cors);  
  14.   
  15.             config.Routes.MapHttpRoute(  
  16.                 name: "DefaultApi",  
  17.                 routeTemplate: "api/{controller}/{id}",  
  18.                 defaults: new { id = RouteParameter.Optional }  
  19.             );  
  20.         }  
  21.     }  
  22. }  

Run the Web API and Angular application.

Our Angular application will be loaded and shown as below.

Angular 6 Application with Cosmos DB and Web API 2  
 
You can click the add a new hero button and add some details.
Angular 6 Application with Cosmos DB and Web API 2  
If you check the data explorer in Cosmos DB emulator, you can see one document inside our MyCollection1 collection as below.
 
Angular 6 Application with Cosmos DB and Web API 2  

You can edit and delete heroes using our Angular application.

We have used our local Cosmos DB emulator for testing purpose. You can even reset the existing data in emulator using Reset Data button of emulator.

Angular 6 Application with Cosmos DB and Web API 2  

Please select SQL as API.

Please create the service and after successful creation, you can view the keys in the Keys pane.

Angular 6 Application with Cosmos DB and Web API 2  

Copy the new URI and primary key and paste to our Web.config instead of old keys for local Cosmos DB.

Run the Web API application again and after some time, our new Azure Cosmos database and collection will be created, and you can check the data in Data Explorer pane.

Angular 6 Application with Cosmos DB and Web API 2  

If you refresh our already running Angular application, you can notice that no Hero data will be displayed because we have changed the connection from local Cosmos DBto Azure.

You can add some data again and save it. Please re-open the Data Explorer in Azure and notice that our new data will be shown in the explorer as given below.

Angular 6 Application with Cosmos DB and Web API 2  
 
Happy coding with Angular 6, Cosmos DB and local emulator too!!!

Web API project for this application can be downloaded from 
Github (WebAPI2)

Angular 6 project for this application can be downloaded from 
Github (Angular6)