I have issue where I want to receive data into my property component after they came from the server.
I made something like this in Service:
private events: Event[] = [];
eventChanged = new Subject<any>(); // Edit: added an observable
constructor(private http: HttpClient) {
this.http.get<Event[]>(this.baseUrl)
.subscribe(events => this.events = events);
this.eventChanged.next(this.events.slice()); //Edit: added an information to subscribers that events list changed
}
getEvents(): Observable<Event[]> {
return this.eventChanged.asObservable();
} // Edit: now I use this method to enables subscribers to observable
/* I don't use that method after Edit
showAllEvents(): Event[] {
return [...this.events];
}
*/
And then I use method showAllEvents()
into mine component like this:
private events: Event[] = [];
private calendarEvents: CalendarEvent[] = [];
subscription: Subscription; // Edit: Added a Subscription
getInterestedEvents() {
// this.events = this.el.showAllEvents(); <-- I changed it into observable
this.subscription = this.el.getEvents()
.subscribe(
(events) => {
this.events = events;
});
this.events.forEach(eachEvent => {
let calendarEvent: CalendarEvent = {
start: subDays(startOfDay(new Date()), 1),
end: addDays(new Date(), 1),
title: eachEvent.name,
color: colors.red
}
this.calendarEvents.push(calendarEvent);
})
}
I don't know how to make this.events
to wait for data from service. Any ideas? On every page it looks different and now I feel like a fool.
Edit
I made a subscribe and observable but still this.el.getEvents().subscribe...
dosen't return any data in my component.
You can create a subscription in your service that notifies if event list changed
eventChanged = new Subject<Event[]>();
in your component, you'll want to subscribe to the eventChanged, in case event list has changed
this.subscription = this.eventService.eventChanged
.subscribe(
(event: Event[]) => {
this.events = events;
}
);
Then add a next
in your service to notify of event changed every time any component updates it, and make it resend the list of events, or whatever you want
addEvent(event: Event) {
this.events.push(event);
this.eventChanged.next(this.events.slice());
}
In case we have event viewer, event editor components, and event service
Setup event service to have a subject (event changed), accessor (get events) adder (update events)
import { Injectable } from '@angular/core';
import {Subject} from 'rxjs/Subject';
@Injectable()
export class EventService {
eventChanged = new Subject<string[]>();
events: string[] = [
'Pizza Party',
'Hackacthon',
'Movie Night'
]
constructor() { }
addEvent(event: string) {
this.events.push(event);
this.eventChanged.next(this.events.slice());
}
getEvents() {
return this.events.slice();
}
}
Then component EventViewer, gets the list, as well as subscribes for any changes
event-viewer.component.ts
import { Component, OnInit } from '@angular/core';
import {EventService} from '../event.service';
import {Subscription} from 'rxjs/Subscription';
@Component({
selector: 'app-event-viewer',
templateUrl: './event-viewer.component.html',
styleUrls: ['./event-viewer.component.css']
})
export class EventViewerComponent implements OnInit {
subscription: Subscription;
events: string[] = this.eventService.getEvents();
constructor(private eventService: EventService) { }
ngOnInit() {
this.subscription = this.eventService.eventChanged
.subscribe(
(events: string[]) => {
this.events = events;
}
)
}
}
So then we render it out
event-viewer.component.html
<ul>
<li *ngFor="let event of events">{{event}}</li>
</ul>
Lastly we want an event editor component
event-editor.component.ts
import { Component, OnInit } from '@angular/core';
import {EventService} from '../event.service';
@Component({
selector: 'app-event-edit',
templateUrl: './event-edit.component.html',
styleUrls: ['./event-edit.component.css']
})
export class EventEditComponent implements OnInit {
eventNumber: number = 1;
constructor(private eventService: EventService) { }
ngOnInit() {
}
addEvent()
{
this.eventService.addEvent(this.eventNumber.toString())
this.eventNumber++;
}
}
and render a button for the user to control
event-editor.component.ts
<button (click)="addEvent()">Add event {{eventNumber}}</button>
In the module of choice we'll obviously have to declare these components, enlist the provider
app.module.ts
@NgModule({
declarations: [
EventViewerComponent,
EventEditComponent
],
imports: [
CommonModule
],
providers: [EventService]
})
So then in then we render both components
app.component.ts
<app-event-viewer></app-event-viewer>
<app-event-edit></app-event-edit>
Now every time we click on button in one component, the other component gets the updated list