0
Hey, guys, all right?
I’m starting my studies with angular and I’m having an implementation problem. I have an API, developed by me, in which the returned data is updated every 20 seconds on the server.
I’m mounting an angled frontend. The idea is to update the user view every 20 seconds too (or less until). But there is a functional requirement of the application, which boils down to notifying (visually) the user, when attribute value is changed.
For a component rendered as follows:
<div *ngFor="event in events">
<app-event
[id]="event.id"
[time]="event.time"
[value1]="event.value1" >
</app-events>
</div>
Being an example call (call n)
"events" : [
{
"id" : 1
"time" : 45,
"value1" : 1.6
},
{
"id" : 2
"time" : 78,
"value1" : 1.5
}
]
In the n+1 call:
"events" : [
{
"id" : 1
"time" : 46,
"value1" : 1.5
},
{
"id" : 2
"time" : 78,
"value1" : 1.6
}
]
The values of time
and value1
were changed in the api in the n+1 call, therefore, I need to change the Component class that it was rendered in call n. I read about issues involving Subject, Observable and other things, but it wasn’t so clear to me, how to perform this.
Below the current code of my components.
events.component.ts
import { Component, OnInit, Input } from '@angular/core';
import { EventsService } from '../../services/events.service';
@Component({
selector: 'app-events',
templateUrl: './events.component.html',
styleUrls: ['./events.component.scss']
})
export class EventsComponent implements OnInit {
events = []
constructor(private eventsService: EventsService) { }
ngOnInit(): void {
this.eventsService.getEvents().subscribe((data: any[]) => {
this.events = data
})
}
}
events.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, Subject } from 'rxjs'
@Injectable({
providedIn: 'root'
})
export class EventsService {
constructor(private httpClient: HttpClient) {
}
private API_URL = "http://0.0.0.0:93"
public getEvents(): Observable<any> {
return this.httpClient.get(`${this.API_URL}/events/inplay`)
}
}
events.component.html
<div *ngFor="let event of events.data">
<app-event [event]="event"></app-event>
</div>
event.component.ts
import { Component, Input, OnChanges, } from '@angular/core';
import { SimpleChanges } from '@angular/core'
import { EventsComponent } from '../events.component';
@Component({
selector: 'app-event',
templateUrl: './event.component.html',
styleUrls: ['./event.component.scss']
})
export class EventComponent implements OnChanges {
@Input() event: any;
constructor(private eventsComponent: EventsComponent) {
}
ngOnInit(): void {
}
ngOnChanges(changes: SimpleChanges) {
console.log(changes)
}
}
Thanks.
So much Subject as Behaviour Subject are indicated for data updates between components that need to update values of one component through another component rather than data from an API. I think this is very simple to solve by inserting a method
JavaScript
setInterval() on the service call in the fileevents.component.ts
, this would update the data at the time determined in the method, or, use methods specific to theAngular/RXJS
for this, as thetimer
: https://rxjs.dev/api/index/function/timer– LeAndrade
All right, I even did that and I forgot to put it in the sample codes. The problem is: How will I identify that the data has been changed and notify the user (visually, a class change, for example) of this change?
– Patrick Acioli
I don’t know if there are methods ready for this, or, I would have to create in hand. But if you’re not ready you can compare the values of the objects in this.Events. Takes the current value and checks if the value the update brought is still equal to the current one.
– LeAndrade
Yes, currently this application is built in Jquery and I do exactly like this. I believe it will be the only alternative.
– Patrick Acioli
You can use sockets instead of http, then your back notifies the front that something has changed
– Eduardo Vargas