Loading frontend/model/Base.mjs 0 → 100644 +66 −0 Original line number Diff line number Diff line function toMap(objs) { return new Map(objs.map(obj => [obj.id, obj])) } export class Base { /** * A Map mapping ids to instances of `Base`. * Must be treated as private. */ static _byId = null /** * @return A list of all instances of `Base` */ static get all() { return this._byId ? Array.from(this._byId.values()) : null } /** * @param {str} id A id * @returns The instance with the given id, if it exists */ static get(id) { return this._byId ? this._byId.get(id) : null } /** * Load the objects from the API, unless the objects have already been loaded. * They are then stored in `this.byUid`. * * @returns Nothing. */ static async load() { if (!this._byId) { const objects = await this.forceLoad() // Hack: We get plain JSON objects from the server, however, we'd like // them to actually be instances of the classes we define. So, we first create a new empty // instance of whatever subclass of `Base` we are currently in using `new this()`, // and then copy all properties from the plain object over to the instance // using `Object.assign`. const instances = objects.map(obj => Object.assign(new this(), obj) ) this._byId = toMap(instances) } } /** * If the objects were already loaded, forget them and load them again. * If the objects were not yet loaded, don't do anything. */ static refresh() { if (this._byId) { this._byId = null this.load() } } /** * Load the objects from the API and return them. * Abstract method, must be overriden in child classes. * * @returns A list of instances. */ static async forceLoad() {} } Loading
frontend/model/Base.mjs 0 → 100644 +66 −0 Original line number Diff line number Diff line function toMap(objs) { return new Map(objs.map(obj => [obj.id, obj])) } export class Base { /** * A Map mapping ids to instances of `Base`. * Must be treated as private. */ static _byId = null /** * @return A list of all instances of `Base` */ static get all() { return this._byId ? Array.from(this._byId.values()) : null } /** * @param {str} id A id * @returns The instance with the given id, if it exists */ static get(id) { return this._byId ? this._byId.get(id) : null } /** * Load the objects from the API, unless the objects have already been loaded. * They are then stored in `this.byUid`. * * @returns Nothing. */ static async load() { if (!this._byId) { const objects = await this.forceLoad() // Hack: We get plain JSON objects from the server, however, we'd like // them to actually be instances of the classes we define. So, we first create a new empty // instance of whatever subclass of `Base` we are currently in using `new this()`, // and then copy all properties from the plain object over to the instance // using `Object.assign`. const instances = objects.map(obj => Object.assign(new this(), obj) ) this._byId = toMap(instances) } } /** * If the objects were already loaded, forget them and load them again. * If the objects were not yet loaded, don't do anything. */ static refresh() { if (this._byId) { this._byId = null this.load() } } /** * Load the objects from the API and return them. * Abstract method, must be overriden in child classes. * * @returns A list of instances. */ static async forceLoad() {} }