banner



How To Run Angular App In Visual Studio Code

Introduction

One of the most common and ever-growing applications in the Web space these days are Single Page Applications (SPA) which are developed used JavaScript frameworks such as Angular, React, etc. for the application's front end. You will find many articles and tutorials on building Angular applications out there using Visual Studio Code. However, Visual Studio 2019 comes with a very neat template for building Angular applications. In this article, we will explore this template and how to enhance it and add our own functionality to it.


Visual Studio 2019 Angular Template

In order to build an Angular front-end application in Visual Studio, we need to follow the below steps:

Then, enter the solution and project name. After that,

Select the Angular template and click "Create"

This will create an Angular application with two components:

  1. A Web API back end application
  2. An Angular front-end application

Below is the structure of the application:

We can build and run this skeleton application. We will get the below screenshot:

If we click the fetch data link, a call is made to the Weather Forecast Controller on the server-side and the data is returned and displayed on the page, as shown below:

The version used was Angular 8.

Adding Functionality to our Angular Application

As an example, to add functionality to the application, we will add a Pages table in which we will store data related to a page. This will include the page name, header, content, etc. We will then build the Pages controller which will read data from the table using Entity Framework Core. Then, on the client-side, we will create a new Pages Component that will use a Pages Service to read the data from the Pages Web API on the server and display these pages on the client-side.

We first create the table and add some records, as shown below:

  1. CREATE TABLE  [dbo].[Pages](
  2.     [ID] [int ] IDENTITY(1,1) NOT NULL ,
  3.     [Title] [nvarchar](max ) NULL ,
  4.     [Header] [nvarchar](max ) NULL ,
  5.     [Content] [nvarchar](max ) NULL ,
  6. CONSTRAINT  [PK_Pages] PRIMARY KEY  CLUSTERED
  7. (
  8.     [ID]ASC
  9. )WITH  (PAD_INDEX = OFF , STATISTICS_NORECOMPUTE = OFF , IGNORE_DUP_KEY = OFF , ALLOW_ROW_LOCKS = ON , ALLOW_PAGE_LOCKS = ON ) ON  [ PRIMARY ]
  10. )ON  [ PRIMARY ] TEXTIMAGE_ON [ PRIMARY ]
  11. GO
  12. INSERT INTO  [AngularDB].[dbo].[Pages] (Title,Header,Content) values  ( 'home' , 'Home' , 'This is the Home Page' )
  13. INSERT INTO  [AngularDB].[dbo].[Pages] (Title,Header,Content) values  ( 'about' , 'About' , 'This is the About Page' )
  14. INSERT INTO  [AngularDB].[dbo].[Pages] (Title,Header,Content) values  ( 'privacy' , 'Privacy' , 'This is the Privacy Page' )

Next, we create the Page Class (In a new Models folder), DB Context for Entity Framework Core (In a new Data folder), and the Pages Controller, as below, to complete the server-side Web API pieces:

  1. namespace  AngularFrontend.Models
  2. {
  3. public class  Page
  4.     {
  5. public int  ID { get ; set ; }
  6. public string  Title { get ; set ; }
  7. public string  Header { get ; set ; }
  8. public string  Content { get ; set ; }
  9.     }
  10. }
  1. namespace  AngularFrontend.Data
  2. {
  3. public class  AngularBackendContext : DbContext
  4.     {
  5. public  AngularBackendContext(DbContextOptions<AngularBackendContext> options) : base (options)
  6.         {
  7.         }
  8. public  DbSet<Page> Pages { get ; set ; }
  9.     }
  10. }
  1. using  System.Linq;
  2. using  AngularFrontend.Data;
  3. using  Microsoft.AspNetCore.Mvc;
  4. namespace  AngularFrontend.Controllers
  5. {
  6.     [Route("api/[controller]" )]
  7.     [ApiController]
  8. public class  PagesController : ControllerBase
  9.     {
  10. private readonly  AngularBackendContext _context;
  11. public  PagesController(AngularBackendContext context)
  12.         {
  13.             _context = context;
  14.         }
  15.         [HttpGet]
  16. public  IActionResult Get()
  17.         {
  18.             var pages = _context.Pages.ToList();
  19. return  Ok(pages);
  20.         }
  21.         [HttpGet("{id}" , Name = "Get" )]
  22. public string  Get( int  id)
  23.         {
  24. return "value" ;
  25.         }
  26.         [HttpPost]
  27. public void  Post([FromBody] string  value)
  28.         {
  29.         }
  30.         [HttpPut("{id}" )]
  31. public void  Put( int  id, [FromBody] string  value)
  32.         {
  33.         }
  34.         [HttpDelete("{id}" )]
  35. public void  Delete( int  id)
  36.         {
  37.         }
  38.     }
  39. }

We also need to add the connection string and add the DB context to the services collection, as shown below:

  1. {
  2. "Logging" : {
  3. "LogLevel" : {
  4. "Default" : "Information" ,
  5. "Microsoft" : "Warning" ,
  6. "Microsoft.Hosting.Lifetime" : "Information"
  7.     }
  8.   },
  9. "ConnectionString" : {
  10. "AngularCS" : "Data Source=localhost\\SQLEXPRESS;Initial Catalog=AngularDB;Integrated Security=True"
  11.   },
  12. "AllowedHosts" : "*"
  13. }
  1. public void  ConfigureServices(IServiceCollection services)
  2.         {
  3.             services.AddDbContext<AngularBackendContext>(opts => opts.UseSqlServer(Configuration["ConnectionString:AngularCS" ]));
  4.             services.AddControllersWithViews();
  5.             services.AddSpaStaticFiles(configuration =>
  6.             {
  7.                 configuration.RootPath ="ClientApp/dist" ;
  8.             });
  9.         }

Next, we move on to the Angular client application and create the following:

  1. Pages component
  2. Pages service. This will be used to communicate with the Pages Web API on the server-side
  1. import { Injectable, Inject } from '@angular/core' ;
  2. import { HttpClient } from'@angular/common/http' ;
  3. @Injectable()
  4. exportclass  PageService {
  5. public  _baseUrl: string ;
  6.   constructor(private  http: HttpClient, @Inject( 'BASE_URL' ) baseUrl: string )
  7.   {
  8. this ._baseUrl = baseUrl;
  9.   }
  10.   getPages() {
  11. return this .http. get ( this ._baseUrl + 'api/pages' );
  12.   }
  13. }
  1. import { Component, Inject } from '@angular/core' ;
  2. import { PageService } from'../services/page.service' ;
  3. import { Router } from'@angular/router' ;
  4. @Component({
  5.   selector:'app-pages' ,
  6.   templateUrl:'./pages.component.html'
  7. })
  8. exportclass  PagesComponent {
  9. public  pages: any;
  10.   constructor(private  router: Router, private  pageService: PageService) {
  11. this .pageService.getPages().subscribe(result => {
  12. this .pages = result;
  13.     }, error => console.error(error));
  14.   }
  15. }

The pages HTML template is shown below:

  1. <h1 class = "page-title" >Pages</h1>
  2. <br>
  3. <tableclass = "table" >
  4.   <tr bgcolor="#f9f9f9" >
  5.     <th>Title</th>
  6.     <th>Header</th>
  7.     <th>Content</th>
  8.   </tr>
  9.   <tr *ngFor="let page of pages" >
  10.     <td>
  11.       {{ page.title }}
  12.     </td>
  13.     <td>
  14.       {{ page.header }}
  15.     </td>
  16.     <td>
  17.       {{ page.content }}
  18.     </td>
  19.   </tr>
  20. </table>

We also need to add the component and service to the app.module.ts file and the nav-menu component html file, as shown below:

  1. import { BrowserModule } from '@angular/platform-browser' ;
  2. import { NgModule } from'@angular/core' ;
  3. import { FormsModule } from'@angular/forms' ;
  4. import { HttpClientModule, HTTP_INTERCEPTORS } from'@angular/common/http' ;
  5. import { RouterModule } from'@angular/router' ;
  6. import { AppComponent } from'./app.component' ;
  7. import { NavMenuComponent } from'./nav-menu/nav-menu.component' ;
  8. import { HomeComponent } from'./home/home.component' ;
  9. import { CounterComponent } from'./counter/counter.component' ;
  10. import { FetchDataComponent } from'./fetch-data/fetch-data.component' ;
  11. import { PagesComponent } from'./pages/pages.component' ;
  12. import { PageService } from'./services/page.service' ;
  13. @NgModule({
  14.   declarations: [
  15.     AppComponent,
  16.     NavMenuComponent,
  17.     HomeComponent,
  18.     CounterComponent,
  19.     FetchDataComponent,
  20.     PagesComponent
  21.   ],
  22.   imports: [
  23.     BrowserModule.withServerTransition({ appId:'ng-cli-universal'  }),
  24.     HttpClientModule,
  25.     FormsModule,
  26.     RouterModule.forRoot([
  27.       { path:'' , component: HomeComponent, pathMatch: 'full'  },
  28.       { path:'counter' , component: CounterComponent },
  29.       { path:'fetch-data' , component: FetchDataComponent },
  30.       { path:'pages' , component: PagesComponent },
  31.     ])
  32.   ],
  33.   providers: [PageService],
  34.   bootstrap: [AppComponent]
  35. })
  36. exportclass  AppModule { }

The nav-menu component HTML file:

  1. <header>
  2.   <nav
  3. class = "navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3"
  4.   >
  5.     <divclass = "container" >
  6.       <aclass = "navbar-brand"  [routerLink]= "['/']" >AngularFrontend</a>
  7.       <button
  8. class = "navbar-toggler"
  9.         type="button"
  10.         data-toggle="collapse"
  11.         data-target=".navbar-collapse"
  12.         aria-label="Toggle navigation"
  13.         [attr.aria-expanded]="isExpanded"
  14.         (click)="toggle()"
  15.       >
  16.         <spanclass = "navbar-toggler-icon" ></span>
  17.       </button>
  18.       <div
  19. class = "navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse"
  20.         [ngClass]="{ show: isExpanded }"
  21.       >
  22.         <ulclass = "navbar-nav flex-grow" >
  23.           <liclass = "nav-item"
  24.               [routerLinkActive]="['link-active']"
  25.               [routerLinkActiveOptions]="{ exact: true }" >
  26.             <aclass = "nav-link text-dark"  [routerLink]= "['/']" >Home</a>
  27.           </li>
  28.           <liclass = "nav-item"  [routerLinkActive]= "['link-active']" >
  29.             <aclass = "nav-link text-dark"  [routerLink]= "['/counter']" >Counter</a>
  30.           </li>
  31.           <liclass = "nav-item"  [routerLinkActive]= "['link-active']" >
  32.             <aclass = "nav-link text-dark"  [routerLink]= "['/fetch-data']" >Fetch data</a>
  33.           </li>
  34.           <liclass = "nav-item"  [routerLinkActive]= "['link-active']" >
  35.             <aclass = "nav-link text-dark"  [routerLink]= "['/pages']" >Pages</a>
  36.           </li>
  37.         </ul>
  38.       </div>
  39.     </div>
  40.   </nav>
  41. </header>

Now, when we run the application, we can see the below screenshot:

Next, we click the Pages link, we see the below screenshot:

Troubleshooting an Angular Application

While working on the front-end Angular application, I once saw the below error (via the Developer Tools on the Chrome browser)

Refused to load the image 'http://localhost:44380/favicon.ico' because it violates the following Content Security Policy directive: "default-src 'none'". Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.

This was a puzzling error, but after some investigation, I found that this is a generic error that is masking some other error. To find the underlying error, I opened the Developer Command Prompt for Visual Studio 2019 at the client application location and used the below command:

Ng-build watch

This gave me details on what I had done wrong. After I fixed that, I ran it again and got the below screenshot:

After this, everything worked fine.

Summary

In this article, we looked at the creation of a Single Page Application in Angular using the Visual Studio 2019 built-in template. This is a nice template which gives us an ASP.NET Core Web API on the backend and an Angular application on the front-end. We can then customize both the server-side and client-side code to add our desired functionality. I have also mentioned some ways we can troubleshoot issues, especially on the front-end Angular application.

How To Run Angular App In Visual Studio Code

Source: https://www.c-sharpcorner.com/article/creating-an-angular-app-in-visual-studio-2019/

Posted by: walravenvoymaiden.blogspot.com

0 Response to "How To Run Angular App In Visual Studio Code"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel