🚀 Building an Infinite Scroll with Angular and .NET Core API

Table of contents

Infinite scroll is a popular UX pattern where more data loads automatically as you scroll down a page, no need for pagination buttons. In this blog post, we’ll walk through how to implement infinite scrolling in an Angular app, powered by a paginated .NET Core API.
🔧 Tech Stack
Frontend: Angular 14+ (TypeScript, HTML, CSS)
Backend: ASP .NET Core Web API (.NET 6 or 7)
HTTP Client: Angular HttpClient
🧱 Project Overview
We’ll build:
A .NET Core API that serves a paginated list of items
An Angular component that displays these items in a scrollable container
A scroll event handler that triggers additional API calls as you scroll
1️⃣ Create the .NET Core Backend
Start by setting up a simple Web API project:
🔹 Sample Controller: ItemsController.cs
[ApiController]
[Route("api/[controller]")]
public class ItemsController : ControllerBase
{
private static readonly List<string> AllItems = Enumerable.Range(1, 1000)
.Select(i => $"Item {i}")
.ToList();
[HttpGet]
public IActionResult GetItems(int page = 1, int pageSize = 20)
{
var items = AllItems
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToList();
return Ok(items);
}
}
This endpoint returns 20 items at a time by default.
🔹 Enable CORS (Optional if frontend and backend are separated)
In Program.cs:
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
});
});
app.UseCors();
2️⃣ Set Up the Angular Project
Use Angular CLI:
ng new infinite-scroll-demo
cd infinite-scroll-demo
ng generate component infinite-scroll
ng generate service item
3️⃣ Create the Angular Service
📄 item.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class ItemService {
private apiUrl = 'https://localhost:5001/api/items';
constructor(private http: HttpClient) {}
getItems(page: number, pageSize: number): Observable<string[]> {
return this.http.get<string[]>(`${this.apiUrl}?page=${page}&pageSize=${pageSize}`);
}
}
Make sure HttpClientModule is imported in your AppModule.
4️⃣ Create the Infinite Scroll Component
📄 infinite-scroll.component.ts
import { Component, OnInit } from '@angular/core';
import { ItemService } from '../item.service';
@Component({
selector: 'app-infinite-scroll',
templateUrl: './infinite-scroll.component.html',
styleUrls: ['./infinite-scroll.component.css']
})
export class InfiniteScrollComponent implements OnInit {
items: string[] = [];
page = 1;
pageSize = 20;
isLoading = false;
endOfData = false;
constructor(private itemService: ItemService) {}
ngOnInit() {
this.loadItems();
}
loadItems() {
if (this.isLoading || this.endOfData) return;
this.isLoading = true;
this.itemService.getItems(this.page, this.pageSize).subscribe(data => {
if (data.length === 0) {
this.endOfData = true;
} else {
this.items.push(...data);
this.page++;
}
this.isLoading = false;
});
}
onScroll(event: any): void {
const target = event.target;
const atBottom = target.scrollTop + target.clientHeight >= target.scrollHeight - 50;
if (atBottom) {
this.loadItems();
}
}
}
📄 infinite-scroll.component.html
<div class="container" (scroll)="onScroll($event)">
<div *ngFor="let item of items" class="item">
{{ item }}
</div>
<div *ngIf="isLoading" class="loading">Loading...</div>
<div *ngIf="endOfData" class="end">No more items</div>
</div>
📄 infinite-scroll.component.css
.container {
width: 400px;
margin: auto;
height: 80vh;
overflow-y: auto;
border: 1px solid #ccc;
padding: 10px;
}
.item {
padding: 10px;
border-bottom: 1px solid #ddd;
}
.loading, .end {
text-align: center;
padding: 10px;
color: gray;
}
🔁 How It Works
On initialization, the component fetches the first page of items.
When the user scrolls near the bottom of the container, it fetches the next page.
It stops loading when the API returns an empty array.
🧪 Tips for Real Projects
Handle error states in the UI
Integrate a loading spinner
You can also use ngx-infinite-scroll if you prefer a library
You can reuse the same backend and logic to implement infinite scroll in a custom dropdown.
✅ Conclusion
We’ve built a fully functional infinite scroll component using Angular and .NET API pagination. This setup gives you full control and a clean separation of frontend and backend responsibilities.
🔗 Resources
Angular Docs: https://angular.io/docs
.NET Web API Docs: https://learn.microsoft.com/aspnet/core/web-api
Subscribe to my newsletter
Read articles from Pranali Kulkarni directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
