This page is part of a static HTML representation of TriTarget.org at https://tritarget.org

Simple Model Manager

Sukima 20th November 2019 at 10:46am
import Route from '@ember/routing/route';

class Adapter {
  ajax() {
    return fetch(...arguments).then(r => r.json());
  }
  query(params) {
    return this.ajax('/api/models');
  }
  create(data) {
    return this.ajax('/api/models', { method: 'POST', data });
  }
  read(id) {
    return this.ajax(`/api/models/${id}`);
  }
  update(id, data) {
    return this.ajax(`/api/models/${id}`, { method: 'PATCH', data });
  }
  destroy(id) {
    return this.ajax(`/api/models/${id}`, { method: 'DELETE' });
  }
}

class Model {
  constructor(data, adapter) {
    let { id, ...attrs } = data;
    this.adapter = adapter;
    this.data = attrs;
    this.id = id;
    this.isNew = !!this.id;
    this.isDirty = false;
  }
  setAttr(attr, value) {
    this.setAttrs({ [attr]: value });
    return this;
  }
  setAttrs(attrs) {
    this.data = { ...this.data, ...attrs };
    this.isDirty = true;
    return this;
  }
  importData({ id = this.id, ...attrs }) {
    this.setAttrs(attrs);
    this.id = id;
    this.isNew = false;
    this.isDirty = false;
    return this;
  }
  async reload() {
    let data = await this.adapter.read(this.id);
    return this.importData(data);
  }
  async save() {
    let data = this.isNew
      ? await this.adapter.create(this.data)
      : await this.adapter.update(this.id, this.data);
    return this.importData(data);
  }
  async destroy() {
    await this.adapter.destroy(this.id);
    this.isDestroyed = true;
    return this;
  }
}

class ModelCollection {
  constructor(records) {
    this.records = records;
  }
  async create(data) {
    let model = new Model(data);
    await model.save();
    this.records.pushObject(model);
    return model;
  }
  async destroy(model) {
    await model.destroy();
    this.records.removeObject(model);
    return model;
  }
}

export default class Route extends Route {
  async model(params) {
    let adapter = new Adapter();
    let results = await adapter.query(params);
    let records = results.map(data => new Model(data, adapter));
    let collection = new ModelCollection(records);
    collection.refreshRoute = () => this.refresh();
    return collection;
  }
}