GitHub · LinkedIn · About · YouTube
Last updated by Kindson Munonye — July 1, 2026
📚 Tutorial hubs:
AI Developer Tutorials ·
Spring Boot ·
Angular ·
CRUD + REST guide
Source code: munonye-ai-chat-spring-angular on GitHub
Estimated reading time: 12–15 minutes · Last updated: July 1, 2026
This Angular OpenAI chat tutorial builds a chat UI on Angular 19 that talks to the Spring AI backend from M7-A. Part of the AI Developer Tutorials hub.
Prerequisites: M7-A backend running on port 8080, Node 18+, Angular CLI 19.
Time: ~50 minutes.
Step 1 — Create the Angular app
ng new chat-ui --routing --style=scss --ssr=false
cd chat-ui
ng serve --port 4200
Configure HttpClient in main.ts:
import { bootstrapApplication } from '@angular/platform-browser';
import { provideHttpClient } from '@angular/common/http';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, {
providers: [provideHttpClient()],
});
Step 2 — Chat service
// chat.service.ts
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
export interface ChatMessage {
role: 'user' | 'assistant';
content: string;
}
@Injectable({ providedIn: 'root' })
export class ChatService {
private http = inject(HttpClient);
private apiUrl = 'http://localhost:8080/api/chat';
send(message: string): Observable<{ reply: string }> {
return this.http.post<{ reply: string }>(this.apiUrl, { message });
}
}
Step 3 — Chat component (standalone)
import { Component, inject, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ChatService, ChatMessage } from './chat.service';
@Component({
selector: 'app-chat',
standalone: true,
imports: [FormsModule],
template: `
<div class="chat">
@for (msg of messages(); track $index) {
<div [class]="msg.role">{{ msg.content }}</div>
}
@if (loading()) { <p>Thinking…</p> }
<form (ngSubmit)="send()">
<input [(ngModel)]="input" name="input" [disabled]="loading()" />
<button type="submit" [disabled]="loading() || !input.trim()">Send</button>
</form>
</div>
`,
styles: [`
.user { text-align: right; color: #1565c0; margin: 8px 0; }
.assistant { text-align: left; color: #2e7d32; margin: 8px 0; }
`],
})
export class ChatComponent {
private chat = inject(ChatService);
messages = signal<ChatMessage[]>([]);
loading = signal(false);
input = '';
send(): void {
const text = this.input.trim();
if (!text) return;
this.messages.update(m => [...m, { role: 'user', content: text }]);
this.input = '';
this.loading.set(true);
this.chat.send(text).subscribe({
next: res => {
this.messages.update(m => [...m, { role: 'assistant', content: res.reply }]);
this.loading.set(false);
},
error: () => {
this.messages.update(m => [...m, { role: 'assistant', content: 'Error contacting AI service.' }]);
this.loading.set(false);
},
});
}
}
Wire ChatComponent in AppComponent imports.
Step 4 — Connect to reactive forms hub
For production forms validation patterns, cross-link Angular reactive forms validation guide.
Next steps
Related:
AI Developer Tutorials hub ·
Angular CRUD Part 1 ·
Spring AI overview