Commit 101670ea authored by Jakob Moser's avatar Jakob Moser
Browse files

Add Base model type from Schwalbe project

parent 95e1ea88
Loading
Loading
Loading
Loading
+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() {}
}