Setup
- Angular 13.2.0
- Ngrx 13.0.2
- Backend: Spring Boot
Goal
I want to continually get the data from the backend. The data is changing and i want to reflect those changes in the angular-app.
What works so far
pollingfetchEntities$ = createEffect(
() => ({ scheduler = asyncScheduler, stopTimer = EMPTY } = {}) =>
this.actions$.pipe(
// Filter action type
ofType(DoctransActions.fetchEntities),
// Get the polling interval
switchMap(() =>
// Start polling
timer(0, 3000, scheduler).pipe(
// Stop the polling (used only in testing)
takeUntil(stopTimer),
switchMap(() =>
this.http.get<DoctransResponse>(`${this.apiUrl}/someurl`).pipe(
map(response => {
return action to set entities
}),
catchError((err) => {
return action for error
)
)
)
)
)
);
Question
Is there a better way for doing this? Maybe i am missing a complete other pattern?
Update 1
Investigating the websocket approach. From here: https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-websocket
it says
Latency alone is not a deciding factor. If the volume of messages is relatively low (for example, monitoring network failures) HTTP streaming or polling can provide an effective solution. It is the combination of low latency, high frequency, and high volume that make the best case for the use of WebSocket. Blockquote
The angular-app will run in the spring-boot-backend. So there wont be any latency. But i dont need real time data (in ms or s). 1 update every 30 sek or every min is good enough.
So maybe HTTP streaming or polling is enough? Dont know this yet. Anyone has some experience with it?
CodePudding user response:
The best way is to use websocket.
import { webSocket } from "rxjs/webSocket";
const subject = webSocket('ws://localhost:8081');
subject.subscribe();
subject.next({message: 'blablabla'});
subject.complete();
You can create a websocket service to manage websocket in your Angular application, as well.
See rxjs documentation for more details.
CodePudding user response:
This is fine if you want to poll for your data. Another option is to use websockets that way the servers can send data to the client.
CodePudding user response:
Websocket is the best way to achieve this but sometimes we can't able to use it in our projects because of backend is not supporting etc...
If the case is you can't use websockets, and you want to poll data from your server another way to achieve it is using interval
from rxjs
loadEntities$ = createEffect(() =>
this.actions$.pipe(
ofType(fromEntityActions.loadEntities),
switchMap(() => interval(1000)),
map(() =>
fromEntityActions.loadEntitiesSuccess({
data: [
{
id: Math.random() > 0.5 ? 1 : 2,
name: "Sefa",
code: "Sefa"
}
]
})
)
)
);
You can try this code, Math.random is just for testing purposes to see if its really changing at 1000ms interval.