How to call Web API in Angular using HttpClient Service

← PrevNext →

We can access Asp.Net Web API methods in an Angular application. Angular 4.3 introduced a new module called the HttpClientModule, which includes HttpClient service that would help initiate http requests and responses. Here in this post I am sharing an example on how to use the new HttpClient Service in Angular to access Web API methods in Asp.Net MVC4 C# and Vb.Net.

Angular HttpClient Service with Web API in Asp.Net MVC 4

The new HttpClientModule is in @angular/common/https package. If you have created an Angular project before, you can check the @angular/common dependency in the package.json file.

Check this post if you are a beginner and haven’t setup Angular 4

Now let’s get started.

I have data in my SQL server database. I’ll make an http request using my Angular app to a Web API controller method, which will access data from an SQL server table and return the data (a List) to the requesting client (my Angular app). I’ll then bind the data to an HTML table in my project template.

First, we’ll create a table in SQL server and add few rows of data to it.

Create SQL Table dbo.Books

CREATE TABLE [dbo].[Books](
    [BookID] [int] IDENTITY(1,1) NOT NULL,
    [BookName] [varchar](50) NULL,
    [Category] [varchar](50) NULL,
    [Price] [numeric](18, 2) NULL,
    PRIMARY KEY CLUSTERED ( [BookID] ASC )
) ON [PRIMARY]

Add data to the table.

Web API (MVC 4)

You should have MVC 4 in Asp.Net installed in your computer.

Note: If you are new to Web API, then please see this post. Its a step-by-step guide to Web Api.

Model Books.cs (C#)
using System;

namespace BooksApp.Models
{
    public class Books
    {
        public int BookID { get; set; }
        public string BookName { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
    }
}
Model Books.vb (Vb.Net)
Imports System.Web

Namespace BooksApp.Models
    Public Class Books
        Public Property BookName() As String
            Get
                Return m_BookName
            End Get
            Set(value As String)
                m_BookName = value
            End Set
        End Property
        Private m_BookName As String

        Public Property BookID() As String
            Get
                Return m_BookID
            End Get
            Set(value As String)
                m_BookID = value
            End Set
        End Property
        Private m_BookID As String

        Public Property Category() As String
            Get
                Return m_Category
            End Get
            Set(value As String)
                m_Category = value
            End Set
        End Property
        Private m_Category As String

        Public Property Price() As Decimal
            Get
                Return m_Price
            End Get
            Set(value As Decimal)
                m_Price = value
            End Set
        End Property
        Private m_Price As Decimal
    End Class
End Namespace

Web API Controller

The Controller in this project has a single public method called Get(), which will handle the http request and return the list of books to the calling application.

BooksController.cs (C#)
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.http;
using System.Web.http;

using BooksApp.Models;
using System.Data.SqlClient;

namespace BooksApp.Controllers
{
    public class BooksController : ApiController
    {

        // LIST OBJECT WILL HOLD AND RETURN A LIST OF BOOKS.
        List<Books> MyBooks = new List<Books>();

        // THE "GET" METHOD WILL RETURN ALL THE BOOKS IN THE TABLE.
        public IEnumerable<Books> Get()
        {
            string sConnString = "Data Source=DNA;Persist Security Info=False;" +
                "Initial Catalog=DNA_Classified;User Id=sa;Password=;Connect Timeout=30;";

            SqlConnection myConn = new SqlConnection(sConnString);

            // THE SQL QUERY TO GET THE BOOKS FROM THE TABLE.
            SqlCommand objComm = new SqlCommand("SELECT *FROM dbo.Books”, myConn);
            myConn.Open();

            SqlDataReader reader = objComm.ExecuteReader();

            // POPULATE THE LIST WITH DATA.
            while (reader.Read())
            {
                MyBooks.Add(new Books
                {
                    BookID = Convert.ToInt32(reader["BookID"]),
                    BookName = reader["BookName"].ToString(),
                    Category = reader["Category"].ToString(),
                    Price = Convert.ToDecimal(reader["Price"])
                });
            }
            myConn.Close();

            return MyBooks;
        }
    }
}
BooksController.vb (Vb.Net)
Option Explicit On

Imports System.Net.http
Imports System.Web.http

Imports System.Data.SqlClient
Imports BooksApp.BooksApp.Models

Namespace BooksApp
    Public Class BooksController
        Inherits ApiController

        ' LIST OBJECT WILL HOLD AND RETURN A LIST OF BOOKS.
        Dim MyBooks As New List(Of Books)()

        ' THE "GET" METHOD WILL RETURN ALL THE BOOKS IN THE TABLE.

        Public Function [Get]() As IEnumerable(Of Books)
            Dim sConnString As String = "Data Source=DNA;Persist Security Info=False;" & _
                "Initial Catalog=DNA_Classified;User Id=sa;Password=;Connect Timeout=30;"

            Dim myConn As New SqlConnection(sConnString)

            ' THE SQL QUERY TO GET THE BOOKS FROM THE TABLE.
            Dim objComm As New SqlCommand("SELECT * FROM dbo.Books", myConn)

            myConn.Open()

            Dim reader As SqlDataReader = objComm.ExecuteReader()

            ' POPULATE THE LIST WITH DATA.
            While reader.Read()
                MyBooks.Add(New Books() With { _
                    .BookID = CInt(reader("BookID")), _
                    .BookName = reader("BookName").ToString(), _
                    .Category = reader("Category").ToString(), _
                    .Price = CDbl(reader("Price")) _
                 })
            End While

            myConn.Close()

            Return MyBooks          ' FINALLY, RETURN THE LIST.
        End Function
    End Class
End Namespace

Once you have created the API, run the application. Don’t close it.

Create Angular Project

Check this post if you are a beginner and haven’t setup Angular yet.

Open the cmd prompt and go to the folder where you want to create the project and type,

ng new angular-with-webapi

Once the project is created, go to the folder.

cd angular-with-webapi

Launch the Server

Launch the server to check if everything is installed properly.

ng serve --open

Import HttpClientModule to the Project

You’ll have to import HttpClientModule in your project to access HttpClient services. Therefore, open app.module.ts file under src/app/ folder inside your project folder.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/https';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

After you have imported HttpClientModule, you can now import HttpClient service to your components.

Create HttpClient Component to Request Data from API

Open app.component.ts file and copy and paste the code into it.

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/https';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Angular with Web API';

  constructor (private httpService: HttpClient) { }
  myBooks: string [];

  ngOnInit () {
    this.httpService.get('http://localhost:43487/api/books/').subscribe(
      data => {
        this.myBooks = data as string [];
      }
    );
  }
}

After you have saved the data, it will automatically refresh the browser, where your app is running. Remember, you have launched the server.

Note: Check your browser console for any errors. A common error that occurs while working with Web API’s running on a different port is Error: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

Please check this post to resolve the above-mentioned error. You’ll have to configure the Global.asax file in your Asp.Net Web API and run API application again.

What I have done here?

I have injected HttpClient into a constructor class. I am also using the get() method to make a request for data to the Web API.

The get() method has a URL (a different port) pointing to the API.

this.httpService.get('http://localhost:43487/api/books/')

Next, I have declared an array named myBooks of type string. I’ll store the data (provided by the API) into this array.

See how I am using the subscribe() method with a callback method named data =>.

To check if the API is responding to our request, add the console.log() method inside the callback method and check the browser console for results.

data => {
    console.log (data);
    // OR
    console.log (data[0].BookName);
}

If it has received data from the API, we’ll now add the data to the array, to display the result in our application template.

this.myBooks = data as string [];

The Template

The template is our markup where we attach the component properties to an element. This is where we’ll view the data we received through our Web API. I have stored the data in an Array in the component class. I wish to view the data in an HTML table. This is simple. You can also populate the data into a Dropdown list etc.

Open app.commponent.html file. Copy the below code into the file.

<div style="text-align:center;width:500px;">
    <h1> {{title}}! </h1>

    <div style="float:left;padding:10px;margin:0 auto;" *ngIf="myBooks">
        <table>
            <tr>
                <th>Book ID</th>
                    <th>Book Name</th>
                        <th>Category</th>
                            <th>Price</th>
            </tr>
            <tr *ngFor="let books of myBooks">    <!-- LOOP -->
                <td>{{books.BookID}}</td>
                    <td>{{books.BookName}}</td>
                        <td>{{books.Category}}</td>
                            <td>{{books.Price}}</td>
            </tr>
        </table>
    </div>
</div>

I have a <div> element, serving as a container. I am using *ngIf condition to check the array myBooks. Next, I have <table> element with header and rows using <tr>. The <tr> element is running a loop using *ngFor, which extracts data from the array myBooks and displays.

You can try using other elements, such as <ul> and <li>. For example,

<ul *ngFor="let books of myBooks">
    <li>{{ books.BookName + ' - ' + books.Price }}</li>
</ul>

Add Style to the Template

You can add little style to the <table> elements. Open app.components.css file and add the below CSS to it.

th, td {
    font:14px Verdana;
}
table, th, td {
    border:solid 1px #999;
    padding:2px 3px;
    text-align:center;
}
th {
    font-weight:bold;
}

You may add inline CSS too.

Save the files. It will automatically refresh the browser and if everyone is correct, you will see the extracted data on your browser.

Output

Angular with Web API in Asp.Net MVC 4 Example using HttpClient

Error Handling in Angular

You will get errors while making http request. Possible scenarios, your Web API has stopped running or the API (after few updates) got errors. You can handle the errors in your Angular application.

Remember we have added a subscribe() method in our component. Open app.component.ts file and check the method. It has a callback method named data =>. You can add an error handler method as the second callback method like this.

import { HttpErrorResponse } from '@angular/common/https/src/response';
data => {
    this.myBooks = data as string [];
},
(err: HttpErrorResponse) => {
    console.log (err.message);
}

First, import HttpErrorResponse class to the component and add the err:HttpErrorResponse callback method, after the data=> method, separated by a comma. This will show error a message (if any) in your browser console.

← PreviousNext →