Skip to content
This repository has been archived by the owner on Jun 27, 2018. It is now read-only.

Commit

Permalink
Clarify the map() logic
Browse files Browse the repository at this point in the history
- map() turns a JS object to an entry
- transform() turns an entry into a JS object

Moved the map logic to fields and views, removed it from Entry and
Datastore
  • Loading branch information
fzaninotto committed Jun 24, 2015
1 parent 0298ce6 commit bbe95ea
Show file tree
Hide file tree
Showing 8 changed files with 227 additions and 150 deletions.
20 changes: 0 additions & 20 deletions lib/DataStore/DataStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,6 @@ class DataStore {
});
}

createEntry(entityName, identifier, fields) {
let entry = new Entry.mapFromRest(entityName, identifier, fields, {});

fields.forEach(function (field) {
entry.values[field.name()] = field.defaultValue();
});

return entry;
}

mapEntry(entityName, identifier, fields, restEntry) {
let entry = new Entry.mapFromRest(entityName, identifier, fields, restEntry);

return entry;
}

mapEntries(entityName, identifier, fields, restEntries) {
return restEntries.map(e => this.mapEntry(entityName, identifier, fields, e));
}

fillReferencesValuesFromCollection(collection, referencedValues, fillSimpleReference) {
fillSimpleReference = typeof (fillSimpleReference) === 'undefined' ? false : fillSimpleReference;

Expand Down
23 changes: 0 additions & 23 deletions lib/Entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,6 @@ class Entry {
get identifierValue() {
return this._identifierValue;
}

static mapFromRest(entityName, identifier, fields, restEntry) {
if (!restEntry) {
return new Entry(entityName);
}

let identifierValue = null;

fields.forEach(function (field) {
let fieldName = field.name();

if (fieldName in restEntry) {
restEntry[fieldName] = field.getMappedValue(restEntry[fieldName], restEntry);
}
});

// Add identifier value
if (identifier) {
identifierValue = restEntry[identifier.name()];
}

return new Entry(entityName, restEntry, identifierValue);
}
}

export default Entry;
54 changes: 46 additions & 8 deletions lib/Field/Field.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ class Field {
this._order = null;
this._label = null;
this._maps = [];
this._transforms = [];
this._attributes = {};
this._cssClasses = null;
this._validation = { required: false, minlength : 0, maxlength : 99999 };
this._defaultValue = null;
this._editable = true;
this._detailLinkRoute = 'edit';
this._pinned = false;
this.dashboard = true;
this.list = true;
}
Expand Down Expand Up @@ -73,6 +75,9 @@ class Field {
return this._detailLink = isDetailLink;
}

/**
* Add a function to be applied to the response object to turn it into an entry
*/
map(fn) {
if (!fn) return this._maps;
if (typeof(fn) !== "function") {
Expand All @@ -89,6 +94,41 @@ class Field {
return !!this._maps.length;
}

getMappedValue(value, entry) {
for (let i in this._maps) {
value = this._maps[i](value, entry);
}

return value;
}

/**
* Add a function to be applied to the entry to turn it into a response object
*/
transform(fn) {
if (!fn) return this._transforms;
if (typeof(fn) !== "function") {
let type = typeof(fn);
throw new Error(`transform argument should be a function, ${type} given.`);
}

this._transforms.push(fn);

return this;
}

hasTranforms() {
return !!this._transforms.length;
}

getTransformedValue(value, entry) {
for (let i in this._transforms) {
value = this._transforms[i](value, entry);
}

return value;
}

attributes(attributes) {
if (!arguments.length) {
return this._attributes;
Expand Down Expand Up @@ -121,14 +161,6 @@ class Field {
return this._cssClasses;
}

getMappedValue(value, entry) {
for (let i in this._maps) {
value = this._maps[i](value, entry);
}

return value;
}

validation(validation) {
if (!arguments.length) {
return this._validation;
Expand Down Expand Up @@ -163,6 +195,12 @@ class Field {
this._detailLinkRoute = route;
return this;
}

pinned(pinned) {
if (!arguments.length) return this._pinned;
this._pinned = pinned;
return this;
}
}

export default Field;
59 changes: 59 additions & 0 deletions lib/View/View.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,65 @@ class View {
});
}


createEntry() {
let entry = new Entry(this.entity.name());
this._fields.forEach(field => {
entry.values[field.name()] = field.defaultValue();
});
return entry;
}

/**
* Map a JS object from the REST API Response to an Entry
*/
mapEntry(restEntry) {

if (!restEntry || Object.keys(restEntry).length == 0) {
return this.createEntry();
}

// clone restEntry
let values = {};
for (let name in restEntry) {
values[name] = restEntry[name];
}

this._fields.forEach(field => {
let fieldName = field.name();
if (fieldName in values) {
values[fieldName] = field.getMappedValue(values[fieldName], values);
}
});

return new Entry(this.entity.name(), values, values[this.entity.identifier().name()]);
}

mapEntries(restEntries) {
return restEntries.map(e => this.mapEntry(e));
}

/**
* Transform an Entry to a JS object for the REST API Request
*/
transformEntry(entry) {

// clone entry values
let restEntry = {};
for (let name in entry.values) {
restEntry[name] = entry.values[name];
}

this._fields.forEach(field => {
let fieldName = field.name();
if (fieldName in restEntry) {
restEntry[fieldName] = field.getTransformedValue(restEntry[fieldName])
}
});

return restEntry;
}

/**
*
* @param {Boolean} optimized
Expand Down
39 changes: 0 additions & 39 deletions tests/lib/DataStore/DataStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,6 @@ describe('DataStore', function() {
dataStore = new DataStore();
});

it('should map some raw entities', function () {
var view = new View();
view
.addField(new Field('title'))
.setEntity(new Entity().identifier(new Field('post_id')));

var entries = dataStore.mapEntries(view.entity.name(), view.identifier(), view.getFields(), [
{ post_id: 1, title: 'Hello', published: true},
{ post_id: 2, title: 'World', published: false},
{ post_id: 3, title: 'How to use ng-admin', published: false}
]);

assert.equal(entries.length, 3);
assert.equal(entries[0].identifierValue, 1);
assert.equal(entries[1].values.title, 'World');
assert.equal(entries[1].values.published, false);
});

it('should map some one entity when the identifier is not in the view', function () {
var view = new View(),
field = new Field('title'),
entity = new Entity('posts');

view
.addField(field)
.setEntity(entity);

entity
.identifier(new Field('post_id'));

var entry = dataStore.mapEntry(entity.name(), view.identifier(), view.getFields(), {
post_id: 1,
title: 'Hello',
published: true
});
assert.equal(entry.identifierValue, 1);
assert.equal(entry.values.title, 'Hello');
});

describe('getReferenceChoicesById', function () {
it('should retrieve choices by id.', function () {
var ref = new ReferenceField('human_id'),
Expand Down
49 changes: 0 additions & 49 deletions tests/lib/EntryTest.js

This file was deleted.

12 changes: 6 additions & 6 deletions tests/lib/Queries/WriteQueriesTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ describe('WriteQueries', () => {
restWrapper.createOne = sinon.stub().returns(buildPromise({data: rawEntity}));

writeQueries.createOne(view, rawEntity)
.then((rawEntry) => {
.then(rawEntry => {
assert(restWrapper.createOne.calledWith(rawEntity, 'cat', 'http://localhost/cat'));

let dataStore = new DataStore();
let entry = dataStore.mapEntry(entity.name(), view.identifier(), view.getFields(), rawEntry);
let entry = view.mapEntry(rawEntry);
assert.equal(entry.values.data.name, 'Mizu');
});
});
Expand All @@ -58,22 +58,22 @@ describe('WriteQueries', () => {

it('should PUT an entity when calling updateOne', () => {
writeQueries.updateOne(view, rawEntity)
.then((rawEntry) => {
.then(rawEntry => {
assert(restWrapper.updateOne.calledWith(rawEntity, 'cat', 'http://localhost/cat/3'));

let dataStore = new DataStore();
let entry = dataStore.mapEntry(entity.name(), view.identifier(), view.getFields(), rawEntry);
let entry = view.mapEntry(rawEntry);
assert.equal(entry.values.data.name, 'Mizute');
});
});

it('should PUT an entity when calling updateOne with an id', () => {
writeQueries.updateOne(view, rawEntity, 3)
.then((rawEntry) => {
.then(rawEntry => {
assert(restWrapper.updateOne.calledWith(rawEntity, 'cat', 'http://localhost/cat/3'));

let dataStore = new DataStore();
let entry = dataStore.mapEntry(entity.name(), view.identifier(), view.getFields(), rawEntry);
let entry = view.mapEntry(rawEntry);
assert.equal(entry.values.data.name, 'Mizute');
});
});
Expand Down
Loading

0 comments on commit bbe95ea

Please sign in to comment.