here in this component when i am write anything than based on the isMeeting Meeting api and AiResponse api is called but here when isMeeting is false than it is also call Meeting api in AiInteraction and when isMeeting is true than it is also call aiinteraction api but when i am refresh the page and perform the task than everything is fine but multiple API calls are being triggered when navigating between the /ai-interactions and /meeting-notes routes also this is demo github import { Component, HostListener, Inject, ChangeDetectorRef, ElementRef, Input, } from '@angular/core'; import { CeateOpenaiService } from '../../create-openai/ceate-openai.service'; import { ActivatedRoute, Router } from '@angular/router'; import { L10N_LOCALE, L10nLocale } from 'angular-l10n'; import { ToastrService } from 'ngx-toastr'; import { Subscription } from 'rxjs'; @Component({ selector: 'app-ai-interactions', templateUrl: './ai-interactions.component.html', styleUrl: './ai-interactions.component.scss', }) export class AiInteractionsComponent { sortColumn: string = ''; sortDirection: 'asc' | 'desc' = 'asc'; showModal: boolean = false; selectedItem: any = null; modalMessage: string = ''; modalTitle: string = ''; dropdownIndex: number = -1; dataresponse: any; data: any[] = []; paginationMeta: any = {}; currentPage: number = 1; perPage: number = 15; projectId: number = 0; isHideRow: boolean = true; dropdownOpen = false; sortBy: string = ''; sortDir: string = ''; page: number = 0; isMeeting: boolean = false; private subscriptions: Subscription[] = []; constructor( private service: CeateOpenaiService, private route: ActivatedRoute, public router: Router, private toastr: ToastrService, private cdr: ChangeDetectorRef, private elementRef: ElementRef, @Inject(L10N_LOCALE) public lang: L10nLocale ) {} ngOnInit() { this.route.params.subscribe((result: any) => { this.projectId = result.id; }); this.handleRowVisibility(); const urlSegments = this.route.snapshot.url.map((segment) => segment.path); this.isMeeting = urlSegments.includes('meeting-notes'); this.getOpenAiResponserequest(this.currentPage); this.listenForNewResponses(); console.log(this.isMeeting , "ngOnit") } ngOnDestroy() { // Clean up subscriptions to avoid memory leaks or multiple subscriptions this.subscriptions.forEach(sub => sub.unsubscribe()); } private handleRowVisibility(): void { const currentUrl = this.router.url; this.isHideRow = currentUrl.includes(`/project/${this.projectId}/ai-interactions`) || currentUrl.includes(`/project/${this.projectId}/meeting-notes`); } getOpenAiResponserequest(page: number) { if(this.isMeeting === false){ console.log("ai call") this.getAiResponse(page) } else{ console.log("meeting call") this.getMeeting(page) } this.cdr.detectChanges(); } getMeeting(page: number){ if(this.isMeeting === true){ this.service.getAllMeetingNotes(page, this.perPage, this.projectId, this.sortBy, this.sortDir) .subscribe((response: any) => { if (response && response.data) { this.data = response.data || []; this.paginationMeta = response.meta || {}; this.currentPage = response.meta?.current_page || 1; } }); } } getAiResponse(page : number){ if(this.isMeeting === false){ this.service .getOpenAiResponse( page, this.perPage, this.projectId, this.sortBy, this.sortDir ) .subscribe((response: any) => { if (response && response.data) { this.data = response.data || []; this.paginationMeta = response.meta || {}; this.currentPage = response.meta?.current_page || 1; } }); } } onSortClick(sortBy: string): void { this.sortDir = this.sortBy === sortBy && this.sortDir === 'asc' ? 'desc' : 'asc'; this.sortBy = sortBy; // if (this.isMeeting) { // this.getMeeting(this.currentPage); // } else { this.getOpenAiResponserequest(this.currentPage); // } } edittxst(dataresponse: any, index: number) { this.dropdownIndex = -1; this.service.setTranscriptionData(dataresponse); this.scrollToTop(); if (this.dropdownIndex === index) { this.dropdownIndex = -1; } } scrollToTop(): void { window.scrollTo({ top: 0, behavior: 'smooth', }); } toggleDropdown(index: number): void { this.dropdownIndex = this.dropdownIndex === index ? -1 : index; } private listenForNewResponses(): void { this.service.newAiResponse$.subscribe((newResponse) => { if (newResponse && newResponse.isUpdate) { this.updateExistingResponse(newResponse); } else if (newResponse && !newResponse.isUpdate) { this.addNewResponse(newResponse); } }); } private updateExistingResponse(newResponse: any): void { const index = this.data.findIndex((item) => item.id === newResponse.id); if (index > -1) { this.data[index] = { ...this.data[index], ...newResponse }; this.cdr.detectChanges(); } } private addNewResponse(newResponse: any): void { this.data = [newResponse, ...this.data]; if (this.isMeeting) { this.getMeeting(this.currentPage); } else { this.getAiResponse(this.currentPage); } this.cdr.detectChanges(); } deleteai(dataresponse: any, index: number): void { this.selectedItem = dataresponse; this.modalMessage = `Are you sure you want to delete this item: "${dataresponse.transcript}"?`; this.modalTitle = 'Confirm Deletion'; this.showModal = true; if (this.dropdownIndex === index) { this.dropdownIndex = -1; } } onModalClose(confirmed: boolean): void { this.showModal = false; if (confirmed && this.selectedItem) { this.deleteResponse(); } this.selectedItem = null; } private deleteResponse(): void { if (this.isMeeting === true) { this.service .deleteMeetingNote(this.projectId, this.selectedItem?.id) .subscribe( (response) => { this.cdr.detectChanges(); this.toastr.success(response.message, 'Success'); this.getOpenAiResponserequest(this.currentPage); }, (error) => { console.error('Error deleting item', error); this.toastr.error('Failed to delete item', 'Error'); } ); } else { this.service.deleteData(this.projectId, this.selectedItem.id).subscribe( (response) => { // this.data = this.data.filter(item => item.id !== this.selectedItem.id); this.cdr.detectChanges(); this.toastr.success('Item deleted successfully', 'Success'); this.getOpenAiResponserequest(this.currentPage) }, (error) => { console.error('Error deleting item', error); this.toastr.error('Failed to delete item', 'Error'); } ); } } nextPage() { this.dropdownIndex = -1 if (this.paginationMeta?.current_page < this.paginationMeta?.last_page) { this.getOpenAiResponserequest(this.paginationMeta?.current_page + 1); } } prevPage() { if (this.paginationMeta?.current_page > 1) { this.getOpenAiResponserequest(this.paginationMeta?.current_page - 1); } } goToPage(page: number) { this.dropdownIndex = -1 if (page >= 1 && page <= this.paginationMeta?.last_page) { this.getOpenAiResponserequest(page); } } getPageNumbers(): number[] { const range: number[] = []; const totalPages = this.paginationMeta?.last_page; const currentPage = this.paginationMeta?.current_page; if (!totalPages || !currentPage) { return range; } const rangeSize = 5; let start = currentPage - Math.floor(rangeSize / 2); let end = currentPage + Math.floor(rangeSize / 2); if (start < 1) { start = 1; end = Math.min(rangeSize, totalPages); } if (end > totalPages) { end = totalPages; start = Math.max(1, totalPages - rangeSize + 1); } for (let i = start; i <= end; i++) { range.push(i); } return range; } } and bellow is my service file import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { environment } from '../../environments/environment'; import axios from 'axios'; import { BehaviorSubject, catchError, Observable, Subject, tap, throwError, } from 'rxjs'; import { CategoryService } from '../services/category.service'; import { ProjectService } from '../services/project.service'; @Injectable({ providedIn: 'root', }) export class CeateOpenaiService { private apiKey = environment.openAI.apiKey; private apiUrls = environment.openAI.openaiapiUrl; private openAiTranscriptionUrl = environment.openAI.openaichatUrl; private newAiResponseSubject = new BehaviorSubject<any>(null); newAiResponse$ = this.newAiResponseSubject.asObservable(); private transcriptionSource = new Subject<string>(); transcription$ = this.transcriptionSource.asObservable(); markdownContent: string = ''; templateId: number | null = null; languageName: string = ''; private getAuthToken(): string | null { return localStorage.getItem('token'); } private createAuthHeaders(): HttpHeaders { const token = this.getAuthToken(); if (!token) { throw new Error('Authentication token is missing'); } return new HttpHeaders().set('Authorization', `Bearer ${token}`); } constructor( private http: HttpClient, private categoryService: CategoryService , private projectService : ProjectService ) { this.categoryService.markdown$.subscribe((markdown) => { this.markdownContent = markdown; }); this.categoryService.templateId$.subscribe((templateId) => { this.templateId = templateId; }); this.projectService.getlanguageid$.subscribe((languageName) => { this.languageName = languageName; }); } fetchProjectById(id: number): void { this.projectService.getProjectById(id).subscribe( (projectResponse) => { if (projectResponse ) { const languageName = projectResponse.data.language.name; this.projectService.setLanguage(languageName); } else { console.error('Project language not found in response'); } }, (error) => { console.error('Error fetching project details', error); } ); } transcribeAudio(file: File, language: string): Observable<any> { const formData = new FormData(); formData.append('file', file); formData.append('model', 'whisper-1'); formData.append('language', language); const headers = new HttpHeaders({ Authorization: `Bearer ${this.apiKey}`, }); return this.http.post(this.openAiTranscriptionUrl, formData, { headers }); } async getResponse(prompt: string): Promise<string> { try { let finalPrompt = ''; if (this.markdownContent && this.markdownContent.trim() !== '') { finalPrompt = `Generate some content based on this text:"${prompt}" \nFollow exactly the below layout and output should be in markdown format: \n${this.markdownContent} `; } else { finalPrompt = `Generate some content based on this text:"${prompt}" \nOutput should be in markdown format. `; } finalPrompt = `Answer the following question in ${this.languageName}: ${finalPrompt}`; const response = await axios.post( this.apiUrls, { model: 'gpt-3.5-turbo', messages: [ { role: 'user', content: finalPrompt, }, ], }, { headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${this.apiKey}`, }, } ); return response.data.choices[0].message.content; } catch (error) { console.error('Error calling OpenAI API', error); return 'Error fetching response'; } } async getMeetingNotesResponse(content: string): Promise<string> { try { const finalPrompt = `Regarding a customer website do the following: generate meeting minutes, a content strategy, a page structure and content for each page based on this conversation which contains text snippets from a call between service agent and customer: "${content}" Output as a structured document following this structure always: 1. **Meeting Minutes** 2. **Content Strategy** 3. **Page Structure** (printed as tree structure) 4. **Content for Each Page** (Include sample text for each page)`; const response = await axios.post( this.apiUrls, { model: 'gpt-3.5-turbo', messages: [ { role: 'user', content: finalPrompt, }, ], }, { headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${this.apiKey}`, }, } ); return response.data.choices[0].message.content; } catch (error) { console.error('Error calling OpenAI API for meeting notes', error); return 'Error fetching meeting note response'; } } createqustion(transcript: any, newEntry: any, id: any): Observable<any> { const headers = this.createAuthHeaders(); const body = { transcript, ai_response: newEntry.ai_response, template_id: newEntry.template_id, }; const aiapi = `${environment.apiServerUrl}/project/${id}/ai-interactions`; return this.http.post<any>(aiapi, body, {headers }).pipe( catchError((error) => { return throwError(error); }), tap((response) => { // this.newAiResponseSubject.next(response); }) ); } getOpenAiResponse( page: number, perPage: number, id: any, sort_by: string, sort_dir: string ): Observable<any> { const headers = this.createAuthHeaders(); const getapi = `${environment.apiServerUrl}/project/${id}/ai-interactions`; return this.http .get<any>( `${getapi}?page=${page}&per_page=${perPage}&sort_by=${sort_by}&sort_dir=${sort_dir}`, { headers } ) .pipe( catchError((error) => { return throwError(error); }) ); } updateTranscription( projectid: number, updatedData: any, aiId: any ): Observable<any> { const headers = this.createAuthHeaders(); const updateapi = `${environment.apiServerUrl}/project/${projectid}/ai-interactions/${aiId}`; return this.http.put(updateapi, updatedData, { headers }).pipe( catchError((error) => { return throwError(error); }), tap((response) => { this.newAiResponseSubject.next(response); }) ); } deleteData(projectid: any, aiId: any): Observable<any> { const headers = this.createAuthHeaders(); const deleteai = `${environment.apiServerUrl}/project/${projectid}/ai-interactions/${aiId}`; return this.http.delete(deleteai, { headers }).pipe( catchError((error) => { return throwError(error); }) ); } addAiResponse(newResponse: any) { this.newAiResponseSubject.next(newResponse); } setTranscriptionData(data: string) { this.transcriptionSource.next(data); } createMeetingNote(projectId: number,noteData: any): Observable<any> { const headers = this.createAuthHeaders(); const url = `${environment.apiServerUrl}/project/${projectId}/meeting-notes`; return this.http.post<any>(url, noteData, { headers }).pipe( catchError((error) => { return throwError(error); }) ); } getAllMeetingNotes( page: number, perPage: number, id: any, sort_by: string, sort_dir: string ): Observable<any> { const headers = this.createAuthHeaders(); const url = `${environment.apiServerUrl}/project/${id}/meeting-notes?page=${page}&per_page=${perPage}&sort_by=${sort_by}&sort_dir=${sort_dir}`; return this.http.get<any>(url, { headers }).pipe( catchError((error) => { return throwError(error); }) ); } getMeetingNote(projectId: number,noteId: number): Observable<any> { const headers = this.createAuthHeaders(); const url = `${environment.apiServerUrl}/project/${projectId}/meeting-notes/${noteId}`; return this.http.get<any>(url, { headers }).pipe( catchError((error) => { return throwError(error); }) ); } updateMeetingNote(projectId: number, updatedData: any ,noteId: number): Observable<any> { const headers = this.createAuthHeaders(); const url = `${environment.apiServerUrl}/project/${projectId}/meeting-notes/${noteId}`; return this.http.put<any>(url, updatedData, { headers }).pipe( catchError((error) => { return throwError(error); }), tap((response) => { this.newAiResponseSubject.next(response); }) ); } deleteMeetingNote( projectId: number,noteId: number): Observable<any> { const headers = this.createAuthHeaders(); const url = `${environment.apiServerUrl}/project/${projectId}/meeting-notes/${noteId}`; return this.http.delete<any>(url, { headers }).pipe( catchError((error) => { return throwError(error); }) ); } } Continue reading...