Prerequisites

Before diving in, make sure you are comfortable with the following technologies:

  • HTML
  • JavaScript
  • TypeScript
  • Node package manager (npm)

Table of Contents

A video walkthrough of this content is also available on my YouTube channel:

Setting Up a Standalone Angular 16 Project

To begin, you first need to verify that Angular is available in your terminal. Running ng version will confirm this. If an error appears, Angular is not yet installed, and you need to run the following command to install it:

npm install -g @angular/cli

Enter fullscreen mode Exit fullscreen mode

After the installation finishes, restart your terminal and execute ng version once more. The output should resemble the image below, showing Angular 16 as the installed version at the time of writing:

Angular Version

With Angular ready, you can now generate a new standalone application by running the following command in your terminal:

ng new ng-client --routing=false --style=css --standalone
Enter fullscreen mode Exit fullscreen mode

This command creates a project named ng-client. Because routing is disabled and the stylesheet format is CSS, the project is set up without a router configuration and uses plain CSS. Navigate into the ng-client directory and start the development server with ng serve --open. The application should load in your browser, displaying the standard Angular welcome page, as shown in the image below:

Angular Template

Creating the Angular Service

In Angular, services are TypeScript classes that encapsulate specific functionalities for your application. For this project, we will use a service to fetch data from a REST API. The first step is to generate the service using the CLI command below:

ng g service service/data
Enter fullscreen mode Exit fullscreen mode

Executing this command creates a new service named DataService within a dedicated service directory.

Configuring provideHttpClient

To set up the service correctly, you need to modify the main.ts file. The relevant code is shown below:

import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { provideHttpClient } from '@angular/common/http';

bootstrapApplication(AppComponent, {
  providers: [provideHttpClient()],
}).catch((err) => console.error(err));
Enter fullscreen mode Exit fullscreen mode

Here’s what the code accomplishes:

  • It begins by importing provideHttpClient from the @angular/common/http package.
  • It then places the provideHttpClient() call inside the providers array.

With this setup, the HttpClient is now available for use, allowing our DataService to interact with the REST API effectively.

Wiring Up the JSON Placeholder REST API

For this tutorial, we'll rely on the publicly available JSON Placeholder API. To get started, a few packages need to be brought into the DataService file.

import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

Following that, we define an interface to establish the expected structure of the data we'll be receiving.

interface Post {
  userId: number;
  id: number;
  title: string;
  body: string;
}

The user id, id, title, and body fields represent the data we plan to showcase in our table. Next, we'll declare a variable to store the REST API endpoint and inject the HttpClient service through the constructor.

apiUrl = 'https://jsonplaceholder.typicode.com/posts';

constructor(private http: HttpClient) {}

Finally, we implement the method that handles the actual HTTP request to the REST API.

getAllPosts(): Observable<Post[]> {
 return this.http.get<Post[]>(this.apiUrl);
}
  • The getAllPosts() method returns an Observable that is typed to Post.
  • Within the return statement, we use the get HTTP method to fetch the data from the provided API URL.

At this point, the complete DataService file is structured as follows:

import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Injectable } from '@angular/core';

interface Post {
  userId: number;
  id: number;
  title: string;
  body: string;
}

@Injectable({
  providedIn: 'root',
})
export class DataService {
  apiUrl = 'https://jsonplaceholder.typicode.com/posts';

  constructor(private http: HttpClient) {}

  getAllPosts(): Observable<Post[]> {
    return this.http.get<Post[]>(this.apiUrl);
  }
}

With the service properly configured, we can now invoke it directly within our component file using dependency injection.

Rendering the Data in an HTML Table

To present the fetched data, we'll move to the app.component.ts file. The necessary logic is implemented in the code snippet below:

  • We start by importing the DataService on line 3, after which we inject it into the component's constructor on line 24.
  • An interface named Post is then created, spanning from line 5 to line 11.
  • On lines 21 and 22, two variables are declared. The posts variable, typed as Post, is initialized with an empty array ([]) and will store the data received from the API. The errorMessage variable is used to capture any potential errors.
  • Inside the ngOnInit lifecycle hook, we execute the logic to pull data from our DataService. On line 27, the getAllPosts() method is invoked. We then subscribe to it, providing two callbacks. The next callback, on line 28, assigns the response data to the previously declared posts variable. The error callback, on line 32, assigns any error information to the errorMessage variable.

With this in place, saving the files and running the ng serve --open command will launch a new browser tab. The console.log statement on line 30 will output the fetched data to the browser's developer console, as shown below:

Data in the console

To visualize this data within a table, we'll clear the default content of the app.component.html file and insert the following markup:

<table>
  <tr>
    <th>id</th>
    <th>title</th>
    <th>body</th>
  </tr>
  <tr *ngFor="let post of posts">
    <td>{{post.id}}</td>
    <td>{{post.title}}</td>
    <td>{{post.body}}</td>
  </tr>
  <tr>
</table>

In the template above, we use the *ngFor directive on the tr element to iterate over the data array. Interpolation ({{}}) is then used to bind the values for id, title, and body properties to the table cells.

After saving these changes, the browser will display the data in a formatted table:

Display data in the table

Wrapping Up

Throughout this guide, we've explored the process of retrieving data for standalone Angular applications using the provideHttpClient function. If you'd like to examine the full source code, you can fork or clone the repository on Github.

If you found this tutorial useful, please consider supporting my work by subscribing to my YouTube channel, where I produce tutorials on web development technologies such as JavaScript, React, Angular, Node.js, and WordPress.