Home > other >  Angular - ngrx - Effect for continually getting data from server
Angular - ngrx - Effect for continually getting data from server

Time:03-14

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.

  • Related