I use the service socket.io
to emit and receive data. When the send button is clicked, it emits data and shows FENEmitInfo
, then receives the data and shows FENSocketioGetCnt
and FENSocketioFilterCnt
.
The console shows data correctly and on time, but the textarea
does not update all the data on time, there is a delay on showing the data the next time.
How can I fix this?
Data showing when the send button is clicked the first time:
Data showing when the send button is clicked the second time:
Data showing when the send button is clicked the third time:
This is app.component.html
:
<div><textarea id="txtarlogAPI" class="border border-red-500 rounded w-full h-96" [value]="logAPIraw"></textarea></div>
<div><button id="btnsendemit01" class="p-1 px-1 border border-red-500 rounded" (click)="sendemit01()">send</button></div>
This is app.component.ts
:
import { Component, OnInit } from '@angular/core';
import {FormsModule} from '@angular/forms';
import {SvsocketService} from './svsocket.service';
@Component({
selector: 'app-root',
standalone: true,
imports: [FormsModule],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
constructor(
private socketService: SvsocketService
){}
SocketioGetCnt: number = 0;
SocketioFilterCnt: number = 0;
SocketioEmitCnt: number = 0;
logAPIraw: string = "";
ngOnInit() {
this.socketService.onMsgSocketAPIEmitInfo().subscribe((dt: string) => {
this.SocketioGetCnt = this.SocketioGetCnt + 1;
console.log('FENSocketioGetCnt:'+this.SocketioGetCnt+', dataget:'+dt);
this.logAPIraw += 'FENSocketioGetCnt:'+this.SocketioGetCnt+', dataget:'+dt+'\n';
if((dt.substring(0, 13))=="API_Info_test"){ //(dt=="API_Info_test")
this.SocketioFilterCnt = this.SocketioFilterCnt + 1;
console.log('FENSocketioFilterCnt:'+this.SocketioFilterCnt+', datafilter:'+dt);
this.logAPIraw += 'FENSocketioFilterCnt:'+this.SocketioFilterCnt+', datafilter:'+dt+'\n';
}
});
}
public sendemit01() {
this.SocketioEmitCnt = this.SocketioEmitCnt + 1;
this.socketService.sendMsgSocketFENEmitInfo("FEN_Info_test_" + this.SocketioEmitCnt.toString());
console.log('FENEmitInfo' + " FEN_Info_test_" + this.SocketioEmitCnt.toString() + ' Finished');
this.logAPIraw += 'FENEmitInfo' + " FEN_Info_test_" + this.SocketioEmitCnt.toString() + ' Finished'+'\n';
}
}
This is svsocket.service.ts
:
import { ApplicationRef, inject, Injectable } from '@angular/core';
import { first, Observable } from 'rxjs';
import {io, Socket} from 'socket.io-client';
@Injectable({
providedIn: 'root'
})
export class SvsocketService {
private socket: Socket;
constructor() {
this.socket = io('http://localhost:3000', { autoConnect: false });
inject(ApplicationRef).isStable.pipe(
first((isStable) => isStable))
.subscribe(() => { this.socket.connect() });
}
sendMsgSocketFENEmitInfo(message: string): void {
this.socket.emit('FENEmitInfo', message);
}
onMsgSocketAPIEmitInfo(): Observable<string> {
return new Observable((observer) => {
this.socket.on('APIEmitInfo', (message: string) => {
observer.next(message);
});
});
}
}
Beside using async pipe, you could also use checkDetector markForChange
export class AppComponent {
logAPIraw: string;
constructor(private cdr: ChangeDetectorRef) {}
sendemit01() {
// Your logic that updates the model
this.logAPIraw = 'newValue';
// Mark for check
this.cdr.markForCheck();
}
}