Build an AI Chatbot With Angular — Complete Beginner Course
Build a modern AI chatbot UI in Angular, from mock responses to a deployed app.
About This Course
Learn how to build an AI chatbot with Angular step by step. Create a modern chat UI, mock AI responses, loading states, error handling, chat history, and deploy your Angular chatbot.
Course Modules
Enroll to save your progress across visits.
- What an AI chatbot is
- How a chatbot works
- What Angular does in an AI chatbot
- Difference between frontend and AI model
- Why we are starting with a mock AI service
What Is a Chatbot?
A chatbot is software that allows users to communicate with a computer using text or voice. For example:
User: What is Angular?
AI: Angular is a TypeScript-based framework used to build modern web applications.
A simple chatbot flow looks like: User Input → Application → Processing → Response → User Interface. An AI chatbot adds an AI model to the processing stage.
Is Angular the AI?
No. Angular is the frontend framework. Angular creates the chat screen, input field, send button, messages, loading indicator, and chat history. The AI model generates the actual intelligent response.
A real application flow: Angular → Backend → AI Model → Backend → Angular.
Why Are We Not Using an API?
Connecting a real API immediately can create unnecessary complexity — API keys, HTTP requests, authentication, backend, security, billing. Instead we build: Angular → Chat Service → Mock AI. Once you understand this architecture, connecting a real AI backend later becomes much easier.
Lesson Exercise
- What is an AI chatbot?
- What is Angular responsible for?
- Does Angular itself generate AI responses?
- Why are we using a Mock AI Service?
- Create an Angular project
- Start the development server
- Create a chatbot component
- Create a chatbot service
- Organize the project
Step 1 — Create the Project
ng new ai-chatbot
cd ai-chatbot
ng serve
Open http://localhost:4200 in your browser.
Step 2 — Create Chat Component
ng generate component components/chat
# or
ng g c components/chat
Step 3 — Create Chat Service
ng generate service services/chat
# or
ng g s services/chat
Recommended Structure
src/
└── app/
├── components/
│ └── chat/
│ ├── chat.component.ts
│ ├── chat.component.html
│ └── chat.component.scss
│
└── services/
└── chat.service.ts
Lesson Exercise
Start the application and confirm it runs successfully at localhost:4200.
- Chat header, message area and input field
- User vs. AI message styling
- The ChatMessage model
Create the Message Model
interface ChatMessage {
role: 'user' | 'assistant';
content: string;
timestamp: Date;
}
The role tells us who created the message — 'user' or 'assistant'.
Component
import { Component } from '@angular/core';
interface ChatMessage {
role: 'user' | 'assistant';
content: string;
timestamp: Date;
}
@Component({
selector: 'app-chat',
templateUrl: './chat.component.html',
styleUrls: ['./chat.component.scss']
})
export class ChatComponent {
messages: ChatMessage[] = [];
userMessage = '';
}
HTML
<div class="chat-container">
<div class="chat-header">
<h2>AI Chatbot</h2>
<p>Ask me anything</p>
</div>
<div class="chat-messages">
<div
*ngFor="let message of messages"
class="message"
[class.user-message]="message.role === 'user'"
[class.ai-message]="message.role === 'assistant'"
>
<strong>{{ message.role === 'user' ? 'You' : 'AI' }}</strong>
<p>{{ message.content }}</p>
</div>
</div>
<div class="chat-input">
<input type="text" [(ngModel)]="userMessage" placeholder="Type your message..." />
<button>Send</button>
</div>
</div>
Basic Styling
.chat-container { width: 100%; max-width: 800px; margin: 40px auto; border: 1px solid #ddd; border-radius: 12px; overflow: hidden; }
.chat-header { padding: 20px; text-align: center; }
.chat-messages { min-height: 400px; padding: 20px; }
.message { padding: 12px 16px; margin-bottom: 12px; border-radius: 12px; max-width: 75%; }
.user-message { margin-left: auto; }
.ai-message { margin-right: auto; }
.chat-input { display: flex; padding: 15px; gap: 10px; }
.chat-input input { flex: 1; padding: 12px; }
At this point the Send button doesn't do anything yet — that's expected, we'll wire it up in the next lessons.
- What an Angular service is
- How dependency injection works
- How to simulate an AI response
- How Observables work
chat.service.ts
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class ChatService {
getAIResponse(message: string): Observable<string> {
const text = message.toLowerCase();
let response = 'I am a demo AI assistant. Please ask me about Angular, TypeScript, or AI.';
if (text.includes('hello') || text.includes('hi')) {
response = 'Hello! How can I help you today?';
} else if (text.includes('angular')) {
response = 'Angular is a TypeScript-based framework used to build modern web applications.';
} else if (text.includes('typescript')) {
response = 'TypeScript is a strongly typed programming language built on JavaScript.';
} else if (text.includes('ai')) {
response = 'AI stands for Artificial Intelligence. It enables computers to perform tasks that normally require human intelligence.';
} else if (text.includes('help')) {
response = 'Sure! Ask me a question about Angular, TypeScript, or AI.';
}
return of(response).pipe(delay(1000));
}
}
How It Works
If the user types Hello, the service returns "Hello! How can I help you today?". If the user types What is Angular?, it returns the Angular explanation. The one-second delay simulates an AI server responding.
- How to capture input
- How to validate input
- How to add messages to an array
- How to call an Angular service
Import and Inject the Service
import { ChatService } from '../../services/chat.service';
constructor(private chatService: ChatService) {}
Create sendMessage()
sendMessage(): void {
if (!this.userMessage.trim()) {
return;
}
const message = this.userMessage.trim();
this.messages.push({
role: 'user',
content: message,
timestamp: new Date()
});
this.userMessage = '';
this.chatService.getAIResponse(message).subscribe(response => {
this.messages.push({
role: 'assistant',
content: response,
timestamp: new Date()
});
});
}
Connect the Button
<button (click)="sendMessage()">Send</button>
The complete flow now works: User types message → Click Send → sendMessage() → User message added → ChatService called → AI response returned → AI message displayed.
- How *ngFor renders the messages array
- Styling user vs. AI message bubbles
Messages are stored in messages: ChatMessage[] = [] and rendered with *ngFor="let message of messages". For example, given:
[
{ role: 'user', content: 'What is Angular?', timestamp: new Date() },
{ role: 'assistant', content: 'Angular is a web framework.', timestamp: new Date() }
]
Angular displays each message as a "You" or "AI" bubble in order.
User and AI Styling
.message { padding: 12px 16px; margin-bottom: 12px; border-radius: 12px; max-width: 75%; }
.user-message { margin-left: auto; background: #2563eb; color: white; }
.ai-message { margin-right: auto; background: #f1f5f9; color: #111827; }
- Why loading feedback matters
- Tracking an isLoading flag
- Showing a "thinking" indicator
AI responses take time. Without a loading state, users may wonder if the chatbot received their message. We solve this with an isLoading flag.
Updated sendMessage()
sendMessage(): void {
if (!this.userMessage.trim() || this.isLoading) {
return;
}
const message = this.userMessage.trim();
this.messages.push({ role: 'user', content: message, timestamp: new Date() });
this.userMessage = '';
this.isLoading = true;
this.chatService.getAIResponse(message).subscribe({
next: (response) => {
this.messages.push({ role: 'assistant', content: response, timestamp: new Date() });
this.isLoading = false;
},
error: () => {
this.isLoading = false;
}
});
}
Display Loading
<div *ngIf="isLoading" class="message ai-message">
AI is thinking...
</div>
- Why production apps need error handling
- Using the RxJS subscribe error callback
- Showing a friendly fallback message
A production application should never assume everything will work — network errors, server errors, invalid responses, API errors, and authentication errors can all happen. Even though our current service is local, we implement error handling now:
this.chatService.getAIResponse(message).subscribe({
next: (response) => {
this.messages.push({ role: 'assistant', content: response, timestamp: new Date() });
this.isLoading = false;
},
error: () => {
this.messages.push({
role: 'assistant',
content: 'Sorry, something went wrong. Please try again.',
timestamp: new Date()
});
this.isLoading = false;
}
});
This gives the user a friendly fallback message instead of a silent failure.
- Saving messages to localStorage
- Loading messages on ngOnInit
- Resetting the conversation with New Chat
The Problem
Refresh the browser and your conversation disappears. We solve this using browser localStorage.
Save Messages
saveMessages(): void {
localStorage.setItem('chat_messages', JSON.stringify(this.messages));
}
Call it whenever the conversation changes.
Load Messages
loadMessages(): void {
const savedMessages = localStorage.getItem('chat_messages');
if (savedMessages) {
this.messages = JSON.parse(savedMessages);
}
}
ngOnInit(): void {
this.loadMessages();
}
New Chat
<button (click)="newChat()">New Chat</button>
newChat(): void {
this.messages = [];
localStorage.removeItem('chat_messages');
}
Now the chatbot supports: Previous conversation → Browser refresh → Conversation restored.
- Creating a production build
- Deployment options
- Why secret API keys never belong in Angular
Create Production Build
ng build
Angular generates production files inside dist/, ready to deploy.
Deployment Options
- Firebase Hosting
- Netlify
- Vercel
- GitHub Pages
- Your own web server
Important Security Lesson
When you eventually connect a real AI API, never put secret API keys directly into Angular:
const API_KEY = 'YOUR_SECRET_API_KEY'; // Never do this
Angular runs in the user's browser, so frontend JavaScript can always be inspected. Instead, route requests through your own backend: Angular → Your Backend → AI Provider → Your Backend → Angular. The backend should securely manage the AI API credentials.
Final Project
Your finished application now supports: user messages, AI responses, mock AI logic, a polished chat UI, loading state, error handling, chat history, New Chat, a responsive interface, and a production build. Congratulations — you've completed Build an AI Chatbot With Angular!
Frequently Asked Questions
Can I build an AI chatbot with Angular?
Yes. Angular is well suited for building the frontend of an AI chatbot, including the chat interface, messages, loading states, error handling, and conversation history.
Do I need an AI API?
No. This beginner course uses a local Mock AI Service. A real AI API can be added later.
Is this Angular chatbot tutorial beginner-friendly?
Yes. The course starts with basic concepts and gradually builds the chatbot feature by feature.
Can I connect OpenAI later?
Yes. You can replace the Mock AI Service with a secure backend that communicates with an AI provider.
Can I connect Google Gemini later?
Yes. The same Angular frontend architecture can be used with a backend connected to Gemini.
What will I build?
You will build a complete Angular chatbot project with a modern chat interface, simulated AI responses, loading states, error handling, chat history, and deployment preparation.