Skip to content

Commit 23dc38f

Browse files
committed
Fix serialization of fresh models + add modifiers to models.
1 parent 9bd8100 commit 23dc38f

File tree

7 files changed

+124
-28
lines changed

7 files changed

+124
-28
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ console.log(article.serialize({ attributes: ['title'], relationships: []}));
129129

130130
`JsonApiDataStoreModel`
131131
- `.serialize(opts)`: serialize a model
132+
- `.setAttribute(attrName, value)`: set or modify attribute of model
133+
- `.setRelationship(relname, models)`: set or modify relationship of model
132134

133135
`JsonApiDataStore`
134136
- `.sync(payload)`: syncs the models described by the payload with the store, and returns the synched models

dist/jsonapi-datastore.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,14 @@ function JsonApiDataStoreModel(type, id) {
77

88
JsonApiDataStoreModel.prototype.serialize = function(opts) {
99
var self = this,
10-
res,
10+
res = { data: { type: this._type } },
1111
key;
1212

1313
opts = opts || {};
1414
opts.attributes = opts.attributes || this._attributes;
1515
opts.relationships = opts.relationships || this._relationships;
1616

17-
res = {
18-
data: {
19-
type: this._type,
20-
id: this.id
21-
}
22-
};
23-
17+
if (this.id !== undefined) res.data.id = this.id;
2418
if (opts.attributes.length !== 0) res.data.attributes = {};
2519
if (opts.relationships.length !== 0) res.data.relationships = {};
2620

@@ -46,6 +40,16 @@ JsonApiDataStoreModel.prototype.serialize = function(opts) {
4640
return res;
4741
};
4842

43+
JsonApiDataStoreModel.prototype.setAttribute = function(attrName, value) {
44+
if (this[attrName] === undefined) this._attributes.push(attrName);
45+
this[attrName] = value;
46+
};
47+
48+
JsonApiDataStoreModel.prototype.setRelationship = function(relName, models) {
49+
if (this[relName] === undefined) this._relationships.push(relName);
50+
this[relName] = models;
51+
};
52+
4953
function JsonApiDataStore() {
5054
this.graph = {};
5155
}

dist/jsonapi-datastore.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/ng-jsonapi-datastore.js

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,18 @@ angular
1010

1111
JsonApiDataStoreModel.prototype.serialize = function(opts) {
1212
var self = this,
13-
res,
13+
res = {
14+
data: {
15+
type: this._type
16+
}
17+
},
1418
key;
1519

1620
opts = opts || {};
1721
opts.attributes = opts.attributes || this._attributes;
1822
opts.relationships = opts.relationships || this._relationships;
1923

20-
res = {
21-
data: {
22-
type: this._type,
23-
id: this.id
24-
}
25-
};
26-
24+
if (this.id !== undefined) res.data.id = this.id;
2725
if (opts.attributes.length !== 0) res.data.attributes = {};
2826
if (opts.relationships.length !== 0) res.data.relationships = {};
2927

@@ -52,6 +50,16 @@ angular
5250
return res;
5351
};
5452

53+
JsonApiDataStoreModel.prototype.setAttribute = function(attrName, value) {
54+
if (this[attrName] === undefined) this._attributes.push(attrName);
55+
this[attrName] = value;
56+
};
57+
58+
JsonApiDataStoreModel.prototype.setRelationship = function(relName, models) {
59+
if (this[relName] === undefined) this._relationships.push(relName);
60+
this[relName] = models;
61+
};
62+
5563
function JsonApiDataStore() {
5664
this.graph = {};
5765
}

dist/ng-jsonapi-datastore.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/jsonapi-datastore/model.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,14 @@ function JsonApiDataStoreModel(type, id) {
77

88
JsonApiDataStoreModel.prototype.serialize = function(opts) {
99
var self = this,
10-
res,
10+
res = { data: { type: this._type } },
1111
key;
1212

1313
opts = opts || {};
1414
opts.attributes = opts.attributes || this._attributes;
1515
opts.relationships = opts.relationships || this._relationships;
1616

17-
res = {
18-
data: {
19-
type: this._type,
20-
id: this.id
21-
}
22-
};
23-
17+
if (this.id !== undefined) res.data.id = this.id;
2418
if (opts.attributes.length !== 0) res.data.attributes = {};
2519
if (opts.relationships.length !== 0) res.data.relationships = {};
2620

@@ -45,3 +39,13 @@ JsonApiDataStoreModel.prototype.serialize = function(opts) {
4539

4640
return res;
4741
};
42+
43+
JsonApiDataStoreModel.prototype.setAttribute = function(attrName, value) {
44+
if (this[attrName] === undefined) this._attributes.push(attrName);
45+
this[attrName] = value;
46+
};
47+
48+
JsonApiDataStoreModel.prototype.setRelationship = function(relName, models) {
49+
if (this[relName] === undefined) this._relationships.push(relName);
50+
this[relName] = models;
51+
};

test/model.js

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ describe('JsonApiDataModel', function() {
7373

7474
var article = store.sync(payload);
7575
var serializedArticle = article.serialize({ attributes: [ 'author' ] });
76-
expect(serializedArticle.data.attributes.title).to.eq(undefined);
76+
expect(serializedArticle.data.attributes.title).to.be.undefined;
7777
});
7878

7979
it('should serialize only specified relationships', function() {
@@ -104,7 +104,85 @@ describe('JsonApiDataModel', function() {
104104

105105
var article = store.sync(payload);
106106
var serializedArticle = article.serialize({ relationships: [ 'author' ] });
107-
expect(serializedArticle.data.relationships.tags).to.eq(undefined);
107+
expect(serializedArticle.data.relationships.tags).to.be.undefined;
108+
});
109+
110+
it('should not serialize the id on fresh models', function() {
111+
var article = new JsonApiDataStoreModel('article');
112+
var serializedArticle = article.serialize();
113+
expect(serializedArticle.data.id).to.be.undefined;
114+
});
115+
});
116+
117+
describe('.setAttribute()', function() {
118+
context('when attribute is not set', function() {
119+
it('should add a new attribute', function() {
120+
var article = new JsonApiDataStoreModel('article');
121+
article.setAttribute('title', 'Cool article');
122+
expect(article.title).to.eq('Cool article');
123+
});
124+
125+
it('should add the new attribute to the list of attributes', function() {
126+
var article = new JsonApiDataStoreModel('article');
127+
article.setAttribute('title', 'Cool article');
128+
expect(article._attributes).to.include('title');
129+
});
130+
});
131+
132+
context('when attribute is set', function() {
133+
it('should modify existing attribute', function() {
134+
var article = new JsonApiDataStoreModel('article');
135+
article.setAttribute('title', 'Cool article');
136+
article.setAttribute('title', 'Cooler article');
137+
expect(article.title).to.eq('Cooler article');
138+
});
139+
140+
it('should not duplicate attribute in the list of attributes', function() {
141+
var article = new JsonApiDataStoreModel('article');
142+
article.setAttribute('title', 'Cool article');
143+
article.setAttribute('title', 'Cooler article');
144+
expect(article._attributes.filter(function(val) { return val == 'title'; }).length).to.eq(1);
145+
});
146+
});
147+
});
148+
149+
describe('.setRelationship()', function() {
150+
context('when relationship is not set', function() {
151+
it('should add a new relationship', function() {
152+
var user = new JsonApiDataStoreModel('user', 13);
153+
user.setAttribute('name', 'Lucas');
154+
var article = new JsonApiDataStoreModel('article');
155+
article.setRelationship('author', user);
156+
expect(article.author.name).to.eq('Lucas');
157+
});
158+
159+
it('should add the new relationship to the list of relationships', function() {
160+
var user = new JsonApiDataStoreModel('user', 13);
161+
user.setAttribute('name', 'Lucas');
162+
var article = new JsonApiDataStoreModel('article');
163+
article.setRelationship('author', user);
164+
expect(article._relationships).to.include('author');
165+
});
166+
});
167+
168+
context('when relationship is set', function() {
169+
it('should modify existing relationship', function() {
170+
var user1 = new JsonApiDataStoreModel('user', 13),
171+
user2 = new JsonApiDataStoreModel('user', 14);
172+
var article = new JsonApiDataStoreModel('article');
173+
article.setRelationship('author', user1);
174+
article.setRelationship('author', user2);
175+
expect(article.author.id).to.eq(14);
176+
});
177+
178+
it('should not duplicate relationship in the list of relationships', function() {
179+
var user1 = new JsonApiDataStoreModel('user', 13),
180+
user2 = new JsonApiDataStoreModel('user', 14);
181+
var article = new JsonApiDataStoreModel('article');
182+
article.setRelationship('author', user1);
183+
article.setRelationship('author', user2);
184+
expect(article._relationships.filter(function(val) { return val == 'author'; }).length).to.eq(1);
185+
});
108186
});
109187
});
110188
});

0 commit comments

Comments
 (0)