From 4deec8949a5f16a2359a1af6e22d13f367e0c1b2 Mon Sep 17 00:00:00 2001 From: Pau Ramon Revilla Date: Tue, 14 Feb 2017 11:56:22 +0100 Subject: [PATCH] Added `isNew` and also `urlRoot` --- __tests__/Model.spec.js | 53 ++++++++++++++++++++++++++++++----------- package.json | 2 +- src/Model.js | 48 +++++++++++++++++++++++++++++++++---- 3 files changed, 84 insertions(+), 19 deletions(-) diff --git a/__tests__/Model.spec.js b/__tests__/Model.spec.js index aaab555..deca66d 100644 --- a/__tests__/Model.spec.js +++ b/__tests__/Model.spec.js @@ -15,13 +15,8 @@ class MyCollection extends Collection { } class MyModel extends Model { - url () { - const id = this.has('id') && this.get('id') - if (id) { - return `/resources/${id}` - } else { - return '/resources' - } + urlRoot () { + return '/resources' } } @@ -46,16 +41,46 @@ describe('Model', () => { model = collection.at(0) }) + describe('isNew', () => { + it('returns true if it does not have an id', () => { + const newModel = new MyModel({}) + expect(newModel.isNew).toBe(true) + }) + + it('returns false if it does not have an id', () => { + const newModel = new MyModel({ id: 4 }) + expect(newModel.isNew).toBe(false) + }) + }) + describe('url', () => { - it('returns the collection one', () => { - expect(model.url()).toBe('/resources/1') + describe('when the model has a collection', () => { + it('returns the collection one', () => { + expect(model.url()).toBe('/resources/1') + }) }) - it('throws if the model does not have a collection', () => { - expect(() => { - const newModel = new Model({ id: 1 }) - newModel.url() - }).toThrowError() + describe('when the model has no collection', () => { + describe('and no urlRoot', () => { + it('throws', () => { + expect(() => { + const newModel = new Model({ id: 1 }) + newModel.url() + }).toThrowError() + }) + }) + + describe('and urlRoot is defined', () => { + it('returns different urls depending whether is new or not', () => { + let newModel + + newModel = new MyModel({}) + expect(newModel.url()).toBe('/resources') + + newModel = new MyModel({ id: 3 }) + expect(newModel.url()).toBe('/resources/3') + }) + }) }) }) diff --git a/package.json b/package.json index fb9897e..8257fe9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mobx-rest", - "version": "1.0.2", + "version": "1.0.3", "description": "REST conventions for mobx.", "repository": { "type": "git", diff --git a/src/Model.js b/src/Model.js index e9adb19..bff3e7e 100644 --- a/src/Model.js +++ b/src/Model.js @@ -1,5 +1,14 @@ // @flow -import { observable, asMap, asFlat, action, asReference, ObservableMap, runInAction } from 'mobx' +import { + observable, + asMap, + asFlat, + action, + asReference, + ObservableMap, + computed, + runInAction +} from 'mobx' import Collection from './Collection' import { uniqueId, isString, debounce } from 'lodash' import apiClient from './apiClient' @@ -27,16 +36,47 @@ export default class Model { } /** - * Return the url for this given REST resource + * Return the base url used in + * the `url` method * * @abstract */ + urlRoot () { + throw new Error('`url` method not implemented') + } + + /** + * Return the url for this given REST resource + */ url (): string { + let urlRoot + if (this.collection) { - return `${this.collection.url()}/${this.get('id')}` + urlRoot = this.collection.url() + } else { + urlRoot = this.urlRoot() } - throw new Error('`url` method not implemented') + if (!urlRoot) { + throw new Error('Either implement `urlRoot` or assign a collection') + } + + if (this.isNew) { + return urlRoot + } else { + return `${urlRoot}/${this.get('id')}` + } + } + + /** + * Wether the resource is new or not + * + * We determine this asking if it contains + * the `id` attribute (set by the server). + */ + @computed + get isNew (): boolean { + return !this.has('id') } /**