OpenSlides/client/src/app/core/services/autoupdate.service.ts

84 lines
3.1 KiB
TypeScript
Raw Normal View History

import { Injectable } from '@angular/core';
import { OpenSlidesComponent } from 'app/openslides.component';
import { WebsocketService } from './websocket.service';
2018-08-24 13:05:03 +02:00
import { CollectionStringModelMapperService } from './collectionStringModelMapper.service';
/**
* Handles the initial update and automatic updates using the {@link WebsocketService}
* Incoming objects, usually BaseModels, will be saved in the dataStore (`this.DS`)
* This service usually creates all models
*
* The dataStore will injected over the parent class: {@link OpenSlidesComponent}.
*/
@Injectable({
providedIn: 'root'
})
export class AutoupdateService extends OpenSlidesComponent {
/**
* Constructor to create the AutoupdateService. Calls the constructor of the parent class.
* @param websocketService
*/
2018-08-29 13:21:25 +02:00
public constructor(websocketService: WebsocketService) {
super();
websocketService.getOberservable<any>('autoupdate').subscribe(response => {
this.storeResponse(response);
});
}
/**
* Handle the answer of incoming data via {@link WebsocketService}.
*
2018-08-24 13:05:03 +02:00
* Bundles the data per action and collection. THis speeds up the caching in the DataStore.
*
* Detects the Class of an incomming model, creates a new empty object and assigns
* the data to it using the deserialize function.
*
* Saves models in DataStore.
*/
public storeResponse(socketResponse: any): void {
2018-08-24 13:05:03 +02:00
// Reorganize the autoupdate: groupy by action, then by collection. The final
// entries are the single autoupdate objects.
const autoupdate = {
changed: {},
deleted: {}
};
// Reorganize them.
socketResponse.forEach(obj => {
if (!autoupdate[obj.action][obj.collection]) {
autoupdate[obj.action][obj.collection] = [];
2018-08-22 16:03:49 +02:00
}
2018-08-24 13:05:03 +02:00
autoupdate[obj.action][obj.collection].push(obj);
});
2018-08-24 13:05:03 +02:00
// Delete the removed objects from the DataStore
Object.keys(autoupdate.deleted).forEach(collection => {
this.DS.remove(collection, ...autoupdate.deleted[collection].map(_obj => _obj.id));
});
// Add the objects to the DataStore.
Object.keys(autoupdate.changed).forEach(collection => {
const targetClass = CollectionStringModelMapperService.getModelConstructor(collection);
2018-08-24 13:05:03 +02:00
if (!targetClass) {
// TODO: throw an error later..
/*throw new Error*/ console.log(`Unregistered resource ${collection}`);
return;
}
2018-09-04 11:33:28 +02:00
this.DS.add(...autoupdate.changed[collection].map(_obj => new targetClass(_obj.data)));
2018-08-24 13:05:03 +02:00
});
}
/**
* Sends a WebSocket request to the Server with the maxChangeId of the DataStore.
* The server should return an autoupdate with all new data.
*
* TODO: Wait for changeIds to be implemented on the server.
*/
public requestChanges(): void {
console.log('requesting changed objects');
// this.websocketService.send('changeIdRequest', this.DS.maxChangeId);
}
}