Angular and the REST
Tags: angular, csharp, javascript
Published: 2019-07-17 13:27:57

This week and the coming one, I'll be writing a new series of articles on how to develop a  full-stack application with Angular v8 on the client-side backed up with ASP.NET Core 2.2 and Node.js respectively. 

The first two installments of this series will cover building an Angular app and connecting it to an ASP.NET Core Web API app. The backend Web API uses SQLite database for storage and also authenticates users by means of JWT (JSON Web Tokens).

The second two installments will look at using the same Angular app, however this time, connecting it to a backend Node.js API app (most likely using Nest.js). The backend API uses a PostgreSQL database for storage and also authenticates users by means of JWT.

Angular is created and maintained by Google and is mainly used for developing Single Page Apps (SPA). On the other hand, ASP.NET Core is created and maintained by Microsoft and can be used to design and build a RESTful Web API that serve client-side apps, including and not limited to, Angular apps.

Today, I'll start building the Angular app to track movies that I've watched and will be watching in the future. The Angular app allows me to perform all CRUD (Create Read Update and Delete) operations on the movies. From the backend side, I will build an ASP.NET Core Web API. For the time being, it will provide a RESTful Endpoint to perform all the CRUD operations on movies and connect to SQLite database. Moreover, I will show you how to use NSwag to enable the Web API to generate Swagger API documentation. With the help of NSwagStudio, we can generate a TypeScript Service based on the Web API Endpoint and embed inside the Angular app. This way, there is no need to generate this code and it saves time.

> In brief, Swagger generates documentation for the Web API that allows any consumer to know what are the capabilities of this API and how to call the different endpoints. You can read more about it here on the [Swagger Website](https://swagger.io/).

> NSwag Nuget Package gives you the APIs needed to configure your Web API to generate Swagger API Documentation. You can read more about it here on [NSwag Github](https://github.com/RicoSuter/NSwag).

> NSwagStudio is a Desktop app provided by the NSwag team to allow you to do code generation. They also offer a command-line too. You can read more about it here [NSwagStudio](https://github.com/RicoSuter/NSwag/wiki/NSwagStudio).

Let's start building the backend Web API.

## Building the ASP.NET Core Web API 
To start building Web APIs with ASP.NET Core, make sure you have the following tools and frameworks locally installed on your machine.

- .NET Core 2.2 Framework [Download](https://dotnet.microsoft.com/download/dotnet-core/2.2)
- Visual Studio 2019 [Download](https://visualstudio.microsoft.com/vs/)

I will be developing this app on a Windows machine. Feel free to use Macbook or any other machine as per your preference.

In the remaining part of this section, we will go through a step by step guide on how to develop the Web API.

The source code for the backend Web API can be found on this Github [repo](https://github.com/bhaidar/movietracker-server).

**Step 1**
Open Visual Studio 2019, locate and click the **Create a new Project** button as you can see below.

![Visual Studio 2019 - Create Project](https://thepracticaldev.s3.amazonaws.com/i/o9mk9iwetulwipjkr873.png)

**Step 2**
Search for the **ASP.NET Core Web Application** template and then click on **Next** button.

![ASP.NET Core Project Template](https://thepracticaldev.s3.amazonaws.com/i/rjheakod2qkwfo2qafy3.png)

**Step 3**
Provide a **Project name**, **Location** and hit **Create** button.

![Configure Project](https://thepracticaldev.s3.amazonaws.com/i/64avyyb8610xrn0fi2lx.png)

**Step 4**
Make sure you select the **Empty** Application Type and hit **Create**.

![Empty Project](https://thepracticaldev.s3.amazonaws.com/i/uyuzx5ytet5n1qnvu9af.png)

This creates a new Empty ASP.NET Core application:

![Visual Studio Project Created](https://thepracticaldev.s3.amazonaws.com/i/4jhw88zmpbg0ecj0m5fl.png)

> The scope of this article is limited to just using ASP.NET Core without going into great depth. If you want more on ASP.NET Core you may visit the official [ASP.NET Core documentation](https://docs.microsoft.com/en-us/aspnet/core/?view=aspnetcore-2.2).

**Step 5**
Add a new class named **Movie.cs** inside the **Model** folder at the root of the application as follows:

{% gist https://gist.github.com/bhaidar/572939e49a9cda33ac047a41d08739dd %}

This will be our model class for a single Movie. I care to record the title of the movie, when I watched it, the movies' genre and my rating on a scale of 1 - 5.

**Step 6**
Now that the Movie model class is created, let's add an Entity Framework Core Database Context that will act as a gateway between the application and the database.

{% gist https://gist.github.com/bhaidar/019dc297e1a21763bb44d01b1d4741fc %}

The **MovieTrackerContext** supports one table for now the **Movies** table.

In addition, it overrides the **OnModelCreating** event handler to instruct EF Core engine on how to create the table inside the database. It customizes the column settings. For instance, the code above defines the column **Id** to be an Auto Increment column. When creating a new record, the database engine will generate a new and unique Id and assign it to this column.

Also, inside the **OnModelCreating** we are seeding some data so that we don't get an empty database.

Finally, install the following SQLite NuGet packages for the application to build and function properly.

```powershell
Install-Package Microsoft.EntityFrameworkCore.Sqlite
Install-Package Microsoft.EntityFrameworkCore.Sqlite.Design
```

> To read more about Entity Framework Core have a look at their official [documentation website](https://docs.microsoft.com/en-us/ef/core/).

**Step 7**
Now that the **MovieTrackerContext** is ready, let's create a migration and update the database accordingly.

Open the **Package Manager Console** and issue the following command to generate a migration that EF Core engine will use to create the database and tables inside accordingly.

```powershell
Add-Migration InitialCreate
``` 

This creates a new migration file that instructs EF Core on how to create the Movie table and how to seed it with some data. Locate the Migrations folder at the root of the application (that was automatically created for you by EF Core engine) and have a look at the migration file.

{% gist https://gist.github.com/bhaidar/28d023457785244e6920f2976a51d33e %}

A migration contains two important methods: Up and Down. The Up method is called when updating the database and running the migration. While the Down method is called when reverting back from a migration to clean up.

**Step 8**
Before you can generate the database structure, you have to introduce the MovieTrackerContext to the EF Core engine by registering the context class inside the ASP.NET Core Dependency Injection internal system.

Locate the **Startup** class and add the following:

```c#
public void ConfigureServices(IServiceCollection services)
{
	services.AddDbContext<MovieTrackerContext>(options => options.UseSqlite(Configuration.GetConnectionString("LocalDb")));
}
```
The **ConfigureServices** method is called by the runtime and it gives the developer a chance to register services inside the Dependency Injection system.

The code registers the MovieTrackerContext as a service by specifying the exact database provider to connect to via a Connection String. 

The Connection String **LocalDb** is defined inside the **appsettings.json** file located at the root of the application.

```json
"ConnectionStrings": {
    "LocalDb": "Data Source=movietracker.db"
  }
```

The connection string specifies the name of the SQLite database that will be created later at the root of the application folder.

The **Configuration** object is also defined inside the Startup class as follows:

```c#
public IConfiguration Configuration { get; }

public Startup(IConfiguration configuration)
{
	Configuration = configuration;
}
```

The Configuration objects gives you access to all configuration information registered in the application.

**Step 9**
Let's create the database, create the Movies table and finally seed the data by running this command inside the Package Manager Console:

```powershell
Update-Database
```

> If you want to query and manipulate the data inside the SQLite database inside Visual Studio, you need to install the [SQLite/SQL Server Compact Toolbox](https://marketplace.visualstudio.com/items?itemName=ErikEJ.SQLServerCompactSQLiteToolbox) Visual Studio extension.

**Step 10**
Now that the Database is ready, let's introduce the MovieTrackerService that contains all the functionality exposed by the Web API endpoints.

Create a new **MovieTrackerService.cs** file inside the **Services** folder (create if it doesn't exist) at the root of the application folder.

Inside the file, add the following contract or interface to define what methods are going to be available on the service:

{% gist https://gist.github.com/bhaidar/3f40abc8b5a05757bc7f1589cceab654 %}

This is a typical set of CRUD operations that a Web API can implement.

Next, add a new **MovieTrackerService** class and let's see how each of the methods above are implemented.

```c#
public MovieTrackerService(MovieTrackerContext context)
{
	this._context = context;
}
```

First of all, the MovieTrackerService requests an instance of the MovieTrackerContext via the constructor. The ASP.NET Core searches for the MovieTrackerContext inside its own Dependency Injection system and creates an instance of the MovieTrackerContext and provides it to the MovieTrackerService. This is a typical example on how Inversion of Control (IoC) works.

```c#
public async Task<List<Movie>> GetMovies() => await this._context.Movies.ToListAsync();
```

The **GetMovies()** method returns all the data inside the Movies table.

```c#
public async Task<Movie> GetMovie(int id) => await this._context.Movies.Where(m => m.Id == id).FirstOrDefaultAsync();
```

The **GetMovie(int id)** method queries for a Movie by Id parameter. The code is constructing a [LINQ query](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/basic-linq-query-operations) to retrieve the data.

```c#
public async Task<Movie> CreateMovie(Movie movie)
{
	await this._context.Movies.AddAsync(movie);
	await this._context.SaveChangesAsync();
	return movie;
}
```

The **CreateMovie(Movie movie)** method adds a new Movie to the database and saves the changes. In addition, it returns the new movie created.

```c#
public async Task DeleteMovie(Movie movie)
{
	this._context.Movies.Remove(movie);
	await this._context.SaveChangesAsync();
}
```
The **DeleteMovie(Movie movie)** method deletes an existing movie from the database and saves the changes.

{% gist https://gist.github.com/bhaidar/a1210a701bc540cabe00f19f5ed479ae %}

The **SearchMovies(string term)** method searches for movies given a search term criteria. It tries to find movies by locating the search term inside the movie title and genre.

```c#
public async Task UpdateMovie(Movie movie)
{
	this._context.Entry(movie).State = EntityState.Modified;
	await _context.SaveChangesAsync();
}
```

Finally, the **UpdateMovie(Movie movie)** method updates an existing movie by setting its **State** to a value of **EntityState.Modified** and then it saves the changes.

The bulk of the Web API implementation is done in this service.

**Step 11**
An ASP.NET Core Web API exposes its function by implementing a Controller. Let's add the **MovieTrackerController** as follows:

{% gist https://gist.github.com/bhaidar/eb2b0de1c2569ca3c807159fe56e8920 %}

The MovieTrackerController is decorated with the **Route** attribute specifying the Endpoint that client-side apps will use to get access to this Web API. 

In practice, a client-side app requests the URL `/api/movietracker` to access this Web API.

In addition, the MovieTrackerController inherits from the **Controller** base class that provides some boilerplate methods that can be used inside the controller.

The controller starts by requesting an instance of the MovieTrackerService via constructor injection. Once again, the ASP.NET Core Dependency Injection system kicks in and provides an instance of this service to the controller.

The controller then defines all actions on this endpoint that can be accessed by the client-side app. For example, let's have a look at the **SearchMovies** action:

```c#
// GET: api/<controller>/search/{title}
[HttpGet("search/{term?}")]
public async Task<ActionResult<IEnumerable<Movie>>> SearchMovies(string term)
{
	return await this._service.SearchMovies(term);
}
```

This action is only accessed by an HTTP Get request in the form of `/api/movietracker/search/{string to search for}`.

The method redirects the call to the MovieTrackerService.SearchMovies() method passing to it the parameters needed.

If you look at the rest of action methods in this controller, they all follow the same strategy by redirecting calls to the MovieTrackerService methods. This is a good design guideline to keep your controllers thin and centralize the business logic inside the services.

Last but not least, we need to register the MovieTrackerService inside the ASP.NET Core Dependency Injection system inside the Startup class:

```c#
public void ConfigureServices(IServiceCollection services)
{
	services.AddDbContext<MovieTrackerContext>(options => options.UseSqlite(Configuration.GetConnectionString("LocalDb")));
	services.AddScoped<IMovieTrackerService, MovieTrackerService>();
}
```

The MovieTrackerService is registered as a Scoped service meaning that one instance of this service is used within a single HTTP Request. For instance, if two controllers request this service, the same instance of the service is passed to both of them.

**Step 12**
Let's add support for Swagger API documentation to our Web API by first installing the following NuGet package from the Package Manager Console window:

```powershell
Install-Package NSwag.AspNetCore
```

Then, open the Startup class and register the Swagger service inside the **ConfigureServices** method as follows:

{% gist https://gist.github.com/bhaidar/7d079b561a46c3914d64d7c102b4343f %}

The Swagger service registration allows you to personalize the Swagger API Documentation page.

Then, tell the ASP.NET Core engine that this application should generate Swagger API Documentation, locate the **Configure** method and register the Swagger API middlewares:

```c#
// Register the Swagger generator and the Swagger UI middlewares
app.UseOpenApi();
app.UseSwaggerUi3();
```

The Configure method is called by the ASP.NET Core runtime and allows the developer to customize the ASP.NET Core Pipeline by registering Middlewares. You can read more about [ASP.NET Core Middlewares](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-2.2).

**Step 13**
Finally, let's add ASP.NET Core MVC engine into the application and run our Web API in the browser. ASP.NET Core MVC is itself built as a service hence it needs to be registered first before using it.

Start by registering the ASP.NET Core MVC services in the Dependency Injection system inside **ConfigureServices** method:

```c#
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
```

Then, register the ASP.NET Core MVC Middleware inside the **Configure** method as follows:

```c#
app.UseMvc();
```

Now we have a complete ASP.NET Core Web API application. Let's give it a shot and try to access it inside Postman requesting the URL:

`GET /api/movietracker/`

And here's the result:

![Postman HTTP Request](https://thepracticaldev.s3.amazonaws.com/i/iuoxxcgn07uewqb8bviy.png)

The application is up and running and ready to serve the Angular app! The rest of the operations Create, Update and Delete a Movie, we will be testing throughout the Angular app soon.

## Building the Angular client-side App 
To start building the Angular app, make sure you have the following tools and frameworks locally installed on your machine.

Angular CLI v8.x [What's new in Angular CLI 8](https://blog.ninja-squad.com/2019/05/29/angular-cli-8.0/)
Node.js 10.x [Node.js Download](https://nodejs.org/en/download)
Visual Studio Code (or any other editor of choice) [VS Code](https://code.visualstudio.com/

In the remaining part of this section, we will go through a step by step guide on how to develop the Angular app and connect it to the backend Web API we just developed.

The source code for the Angular app can be found on this Github [repo](https://github.com/bhaidar/movietracker-client).

**Step 1**
Create an Angular app by running this command on a terminal window:

```bash
ng new movie-watcher-client --style=scss --routing=true`
```

The above command uses the Angular CLI command to create and scaffold an Angular app.

**Step 2**
Add the Angular Material module as we are going to use some of the components and styles provided by this library. Run the following command:

```bash
ng add @angular/material
```

**Step 3**
Let's change the Angular Material theme in our app. Locate the **angular.json** file at the root of the application. Then go to the `architect\build` and `architect\test` nodes and change the Angular Material theme URL to match the one below:

```json
"./node_modules/@angular/material/prebuilt-themes/deeppurple-amber.css"
```

**Step 4**
Let's separate all the modules we want to import from Angular Material into their own module. This way we can reference it easily in other modules instead of spreading around import statements from the Angular Material module.

Run the following command to create a new module:

```bash
ng generate module app-material
```

This command creates a new `app-material.module.ts` file inside a newly created folder located at `src\app\app-material\` folder.

Let's import the needed Angular Material modules for this app inside the `app-material.module.ts` as follows:

{% gist https://gist.github.com/bhaidar/e053662820413d0709e0dd3f90b78b1c %}

**Step 5**
Create a new module to hold all the related components for the Movie Tracker module. Run the following command to create the `movie-tracker.module.ts`:

```bash
ng generate module movie-tracker --routing=true --module=app.module
```

The command generates a new module inside a new folder `\src\app\movie-tracker`.

**Step 6**
Let's generate the `movie-tracker.service.ts` by using the NSwagStudio application. Start by publishing the ASP.NET Core Web API to a folder on the local file system.

Before actually publishing the Web API, open the **MovieTrackerController** class and add the **ApiConventionType** attribute at the class level as follows:

```c#
[ApiConventionType(typeof(DefaultApiConventions))]
public class MovieTrackerController : Controller
```

This attribute is used by Swagger to infer all possible HTTP Responses that a specific Endpoint action might return. You will see this later once we generate the Angular service using NSwagStudio.

Let's focus on publishing the application by following the steps below:

- Open the ASP.NET Core app inside Visual Studio. 

- Right-click the project name and select `Publish`

- Locate the **Start** button and click it

![Start Publishing](https://thepracticaldev.s3.amazonaws.com/i/dun648dklb96td650wof.png)

Select the **Folder** as a publish target. Visual Studio automatically specifies the `publish` folder inside the application path. You may change it or keep it, what matters is to remember this path for later.



Then, locate the **Create Profile** button in the bottom right side of the window.



Locate and click on the **Publish** button to start the publishing process.

**Step 7**
Open the NSwagStudio desktop app:



You specify the source Web API on the right side of the app. While on the left side you specify the output to be generated.

Make sure you select the following under the **Input** section:
- Select the **Runtime** to be **NetCore22**
- Select the tab **ASP.NET Core via API Explorer**
- Under the **Assembly tab** select the main DLL of the ASP.NET Core Web API, in our case it is the following path `D:\Projects\Playground\MovieTracker\Publish\MovieWatcher.Server.dll`
- Under the **Path to search for referenced assembly files** paste in the path for the publish folder, in our case it is the following path `file://D:/Projects/Playground/MovieTracker/Publish`

Make sure you select the following under **Output** section:
- Select the **Template** to be **Angular**
- Select the **RxJs Version** to be **6.0**
- Select the **Injection Token Type** to be **InjectionToken**
- Under **Class Name** replace the word **Client** with **Service**

Finally, locate and click on the **Generate Outputs** button to get the actual service code generated.

Once done, copy the code and go back to the Angular app inside Visual Studio Code.

**Step 8**
Locate the `movie-tracker` module folder and create a subfolder `services`. Inside this new folder, create the `movie-tracker.service.ts` file and paste in the copied code from NSwagStudio.

{% gist https://gist.github.com/bhaidar/a87d0ca94f997fc8c6a2d7fdfc81baf9 %}

NSwag reads the ASP.NET Core Web API Swagger documentation, infers all the possible HTTP Responses that each Endpoint action might return (based on the attribute we've added) and generates a full Angular service for each and every Endpoint action. In addition, it generates a Typescript model class for the Movie model.

I've amended two things on the generated service.

First, I've added the following decorator to inject the service at the root level of the app:

```typescript
@Injectable({
	providedIn: 'root'
})
```

Second, I've replaced the checking for Status Coed 200 by Status Code 204 inside the **processDelete** method that runs upon receiving a response from the server after deleting a Movie.

That's all! You have a fully functioning Angular service that you can start using right away.

**Step 9**
Let's make use of the proxying support in the webpack dev server used inside the Angular CLI to divert calls for `http://localhost:4200/api/` to the server running on `https://localhost:44342/api`.

Using a proxy file replaces the need to enable CORS inside your ASP.NET Core Web API.

- Create a `proxy.config.js` file inside the `src\` root folder

- Add the following inside the file

```javascript
module.exports = {
  '/api': {
  	target: 'https://localhost:44342/',
    secure: false
  }
};
```

- Go to the`package.json` file and amend the `start` NPM script as follows:

```json
"start": "ng serve --proxy-config proxy.conf.js",
```

Serving the application now will take into consideration the proxy settings and does the redirection automatically for you.
You may read more about [Proxying a Backend Server](https://angular.io/guide/build#proxying-to-a-backend-server) on the Angular website.

**Step 10**
Create the `movie-tracker-grid` component to render the movies data in a table.

Run the following command to create a new component:

```bash
ng g component movie-tracker/components/movie-tracker-grid --module=movie-tracker --skipTests=true --inlineTemplate=true --inlineStyle=true
```

The command creates the MovieTrackerGridComponent inside the `movie-tracker/components` folder.

Paste in the following HTML Markup and code:

{% gist https://gist.github.com/bhaidar/9f14905dad802657d285779cc8bec346 %}

The component renders a table using the Angular Material Table module. The component defines the columns to show inside the table: Title, WatchOn, Genre and Rating. In addition, it defines the **Action** column that contains the **Edit** and **Delete** buttons.

Right before rendering the table, we add a button to allow the user to create a new Movie.

The component accepts as input the Movies' data to display.
Also, the component defines an output of type `EventEmitter` that emits actions like `Edit`, `Delete` and `Create`.

Eventually, when we run the application, the table would look like this:

![Movie List](https://thepracticaldev.s3.amazonaws.com/i/dvpjy42o0yp25w2n3fdq.png)

**Step 11**
Let's create the Search Bar component that allows us to search and filter the Movies.

Run the following command to create a new component:

```bash
ng g component movie-tracker/components/movie-tracker-search-bar --module=movie-tracker --skipTests=true --inlineTemplate=true --inlineStyle=true
```

The command above creates the MovieTrackerSearchBarComponent inside the `movie-tracker/components` folder.

Paste in the following HTML Markup and code:

{% gist https://gist.github.com/bhaidar/c1fefe5cd7a8347f73bb346785ad3748 %}

The component is straightforward. It defines an Input control that allows the user to filter the Movies data.

Inside the `ngOnInit()` method it creates an **Observable** that wraps the Input's `keyup` event and emits as output the text the user has typed.

**Step 12**
Let's now combine both the `movie-tracker-grid` and `movie-tracker-search-bar` components into the `movie-tracker-list` component to have a fully functional and useful component.

Run the following command to create a new component:

```bash
ng g component movie-tracker/containers/movie-tracker-list --module=movie-tracker --skipTests=true --inlineTemplate=true --inlineStyle=true
```

This command creates the MovieTrackerListComponent inside the `movie-tracker/containers` folder.

Paste in the following HTML Markup and code:

{% gist https://gist.github.com/bhaidar/e4902ed37b75335af9af1de19da0ec56 %}

The component injects in its constructor the `MovieTrackerService`. Inside the `ngOnInit()` method it calls the `movieService.searchMovies()` method with an empty string to retrieve all data stored in the database.

Whenever the user types any text in the search box the `doAction()` method is triggered. The MovieTrackerSearchBarComponent emits an action of type `search`. The `doAction()` method handles the `search` event type and emits the text typed which in turn causes the `movieService.searchMovies()` method to be triggered again with a new search term.

Run the application by using the command `yarn run start` and let's check the UI we have so far.

![List Mmovies](https://thepracticaldev.s3.amazonaws.com/i/0rh1j1pkbq21ehvsj5xk.png)

If you search the word `fantasy`, the results shown, will be Movies whose title or genre fields contain that word.

![Filter Movies](https://thepracticaldev.s3.amazonaws.com/i/sk3n0fxn5l5iugrqahu0.PNG)


**Step 13**
Let's handle creating, editing and deleting a Movie. We will be using the Angular Material Dialog module to open a popup Modal window to allow the user to do so.

Create the `MovieDialogBoxComponent` by running the following command:

```bash
ng g component movie-tracker/components/movie-dialog-box --module=movie-tracker --skipTests=true --inlineStyle=true
```

The command creates the MovieDialogBoxComponent inside the `movie-tracker/components` folder.

Paste in the HTML markup inside the `movie-dialog-box.component.html` file:

{% gist https://gist.github.com/bhaidar/cfa2a18656e5d4a20c4673cbb3d3abbb %}

The HTML markup displays a simple form to allow the user to create or edit a Movie based on the **action** passed to this component as we will see soon. In addition, we make use of a rating component to allow the user to rate a movie (you can check the code for details of the rating component).

Let's switch back to the `movie-dialog-box.component.ts` file and paste the following code:

{% gist https://gist.github.com/bhaidar/5327501e89954f9326e11713d3da962b %}

> For an in-depth look at Angular Material Dialog module you can read the official documentation at [Angular Material Dialog Module](https://material.angular.io/components/dialog)

The component receives, via its constructor, a data object that defines a movie property (an instance of a movie in the case of editing a movie or an empty object when creating a new movie). In addition, the data object defines the action property to distinguish the operation of creating, editing or deleting a movie.

On submitting the form, the Dialog passes back to the caller the **action** (create, delete or edit) together with the **movie** instance.

**Step 14**
Let's switch back to the `movie-tracker-list` component and handle the `edit`, `create` and `delete` actions.

Paste the following code inside the `movie-tracker-list` component:

{% gist https://gist.github.com/bhaidar/7e592197214b0d4021ac20f6f491a203 %}

Clicking the **Edit** button triggers the action `edit`. This action is handled inside the component that opens the `movie-dialog-box` component to let the user edit the movie:

![Edit Movie](https://thepracticaldev.s3.amazonaws.com/i/wiyewfapjcarhaazpsyc.PNG)

Clicking the **Add Movie** button triggers the action `create`. This action is handled inside the component that opens the `movie-dialog-box` component to let the user create a new movie:

![Create Movie](https://thepracticaldev.s3.amazonaws.com/i/dv6f1n8p7fawjyqj6xbg.PNG)

Clicking the **Delete** button triggers the action `delete`. This action is handled inside the component that opens the `movie-dialog-box` component to allow the user to delete an existing movie:

![Delete Movie](https://thepracticaldev.s3.amazonaws.com/i/cbqcwthfh9ez0xr259q2.PNG)

Right after the `movie-dialog-box` component dialog closes, the table is refreshed to get the latest data from the backend server.

##Conclusion
We've seen how easy it is to connect an Angular app with an ASP.NET Core Web API app. 

In the next article, I will add support for authentication using JSON Web Token (JWT).


*This post was written by [Bilal Haidar](https://www.bhaidar.dev/), a mentor with [This Dot](https://thisdot.co/).*

*You can follow him on Twitter at @bhaidar.*

*Need JavaScript consulting, mentoring, or training help? Check out our list of services at [This Dot Labs](https://thisdot.co).*