ice-frontend-react-mobx
Version:
ICE Frontend REACT+MobX
142 lines (117 loc) • 3.67 kB
JavaScript
const debug = require('debug')('ice:IdStore');
import { observable, action, computed } from 'mobx';
export default class IdStore {
_items = observable.map({});
loading = false;
constructor (options) {
this._fetchFunction = (options && options.fetch) ? options.fetch : null;
this._createFunction = (options && options.create) ? options.create : null;
this._updateFunction = (options && options.update) ? options.update : null;
this._removeFunction = (options && options.remove) ? options.remove : null;
}
// I think these are worth keeping...
getById (key) {
return this.map.get(key);
}
updateItem (item) {
if (!item.id) {
debug('Trying to update an item that does not have an id:', item);
throw new Error('Item does not have an id');
}
return this.map.set(item.id, item);
}
// Main functionality
set items (items) {
// console.log('IdStore::set items==>items:', items);
let map;
let keys;
if (Array.isArray(items)) {
keys = items.map((item) => (item.id));
map = items.reduce(this._mapReducer, {});
} else if (typeof items === 'object') {
keys = Object.keys(items);
map = items;
} else {
debug('Fetch promise return was not an array or object:', items, this);
throw new Error('Fetch promise returned something other than an array.');
}
// clear deleted items
if (items.length < this._items.size) {
let currentKeys = this._items.keys();
let deletedKeys = currentKeys.filter((key) => {
return keys.indexOf(key) === -1;
});
deletedKeys.forEach((key) => {
this._items.delete(key);
});
}
// now merge
this._items.merge(map);
}
get items () {
// console.log('IdStore::get items==>this._items:', this._items);
// console.log('IdStore::get items==>this._items.values():', this._items.values());
return this._items.values();
}
get map () {
return this._items;
}
_mapReducer (map, obj) {
map[obj.id] = obj;
return map;
}
fetch () {
if (!this._fetchFunction) {
debug('No Fetch function defined');
return;
}
this.loading = true;
return this._fetchFunction().then((items) => {
this.loading = false;
// this.items = items;
return items;
});
}
save (item) {
if (!item) {
debug('Trying to save an invalid item:', item);
throw new Error('Trying to save an invalid item.');
} else if (!item.toJson) {
debug('Trying to save something other than a domain object:', item);
throw new Error('toJson not found on save object.');
}
if (!item.id) {
return this._createFunction(item.toJson).then((savedItem) => {
debug('Item Created:', item);
item.updateFromJson(savedItem);
this.map.set(savedItem.id, item);
return item;
});
}
return this._updateFunction(item.toJson).then((savedItem) => {
debug('Updated Item:', item);
item.updateFromJson(savedItem);
return item;
});
}
delete (id) {
return this._items.delete(id);
}
remove (item) {
let id;
// check to see if we have an id or object
if (item && typeof item === 'string') {
// assume we have a string
id = item;
} else if (item && item.id) {
// assume we have an object
id = item.id;
} else {
debug('Trying to remove an inivalid item:', item);
throw new Error('Trying to remove an invalid item.');
}
return this._removeFunction(id).then(() => {
this._items.delete(id);
});
}
}