Skip to content

Commit 20100d6

Browse files
committed
fix: add missing emptiness-check
1 parent 73d4072 commit 20100d6

File tree

4 files changed

+162
-3
lines changed

4 files changed

+162
-3
lines changed

README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# JSON:API deserializer in Typescript
22

3+
A JSON:API response payload is a normalized set of entities and their relationships plus some metadata. This package
4+
deserializes a JSON:API response payload into an object graph, using user-defined entity deserializers to build the
5+
actual entities.
6+
37
## Installation
48

59
```shell
@@ -14,7 +18,7 @@ This example uses the jsonapi.org sample data (added the missing person, though)
1418

1519
```typescript
1620
// Import the package and required interfaces:
17-
import {Item, ItemDeserializer, RelationshipDeserializer} from "jsonapi-ts-deserializer";
21+
import {getDeserializer, Item, ItemDeserializer, RelationshipDeserializer} from "jsonapi-ts-deserializer";
1822

1923
// Have some data to deserialize:
2024
const jsonapiOrgExampleData = {

src/__tests__/Deserializer.test.ts

+125-1
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,119 @@ class CommentDeserializer implements ItemDeserializer {
166166
}
167167
}
168168

169+
// a JSON:API response with a simple directory structure with a couple of files and folders
170+
const fileSystemExampleData = {
171+
data: [
172+
{
173+
type: 'folders',
174+
id: '1',
175+
attributes: {
176+
name: 'root',
177+
},
178+
relationships: {
179+
children: {
180+
data: [
181+
{
182+
type: 'folders',
183+
id: '2',
184+
},
185+
{
186+
type: 'files',
187+
id: '3',
188+
},
189+
],
190+
},
191+
},
192+
}
193+
],
194+
included: [
195+
{
196+
type: 'folders',
197+
id: '2',
198+
attributes: {
199+
name: 'home',
200+
},
201+
relationships: {
202+
children: {
203+
data: [
204+
{
205+
type: 'files',
206+
id: '4',
207+
},
208+
{
209+
type: 'folders',
210+
id: '5',
211+
}
212+
],
213+
},
214+
},
215+
},
216+
{
217+
type: 'files',
218+
id: '3',
219+
attributes: {
220+
name: 'swapfile',
221+
},
222+
},
223+
{
224+
type: 'files',
225+
id: '4',
226+
attributes: {
227+
name: 'README.md',
228+
},
229+
},
230+
{
231+
type: 'folders',
232+
id: '5',
233+
attributes: {
234+
name: 'juha',
235+
}
236+
}
237+
]
238+
}
239+
240+
type Folder = {
241+
id: number;
242+
name: string;
243+
children: (Folder | File)[];
244+
}
245+
246+
type File = {
247+
id: number;
248+
name: string;
249+
}
250+
251+
class FolderDeserializer implements ItemDeserializer {
252+
getType(): string {
253+
return 'folders';
254+
}
255+
256+
deserialize(item: Item, relationshipDeserializer: RelationshipDeserializer): any {
257+
const folder: Folder = {
258+
id: parseInt(item.id),
259+
name: item.attributes.name,
260+
children: [],
261+
};
262+
263+
folder.children = relationshipDeserializer.deserializeRelationships(relationshipDeserializer, item, 'children');
264+
265+
return folder;
266+
}
267+
}
268+
269+
class FileDeserializer implements ItemDeserializer {
270+
getType(): string {
271+
return 'files';
272+
}
273+
274+
deserialize(item: Item, relationshipDeserializer: RelationshipDeserializer): any {
275+
return {
276+
id: parseInt(item.id),
277+
name: item.attributes.name,
278+
};
279+
}
280+
}
281+
169282
describe('Deserializer', () => {
170283
it('deserializes the jsonapi.org example into an object graph', () => {
171284
const deserializer = getDeserializer([
@@ -178,4 +291,15 @@ describe('Deserializer', () => {
178291

179292
expect(rootItems).toMatchSnapshot();
180293
});
181-
});
294+
295+
it('deserializes a file system example into an object graph', () => {
296+
const deserializer = getDeserializer([
297+
new FolderDeserializer(),
298+
new FileDeserializer(),
299+
]);
300+
301+
const rootItems: any[] = deserializer.consume(fileSystemExampleData).getRootItems();
302+
303+
expect(rootItems).toMatchSnapshot();
304+
});
305+
})

src/__tests__/__snapshots__/Deserializer.test.ts.snap

+30
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,35 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`Deserializer deserializes a file system example into an object graph 1`] = `
4+
[
5+
{
6+
"children": [
7+
{
8+
"children": [
9+
{
10+
"id": 4,
11+
"name": "README.md",
12+
},
13+
{
14+
"children": [],
15+
"id": 5,
16+
"name": "juha",
17+
},
18+
],
19+
"id": 2,
20+
"name": "home",
21+
},
22+
{
23+
"id": 3,
24+
"name": "swapfile",
25+
},
26+
],
27+
"id": 1,
28+
"name": "root",
29+
},
30+
]
31+
`;
32+
333
exports[`Deserializer deserializes the jsonapi.org example into an object graph 1`] = `
434
[
535
{

src/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,9 @@ export class Deserializer implements RelationshipDeserializer {
108108
}
109109

110110
deserializeRelationships(relationshipDeserializer: RelationshipDeserializer, item: Item, name: string): any[] {
111-
const relationships = item.relationships[name].data;
111+
if (!item?.relationships || !item.relationships[name]) return [];
112112

113+
const relationships = item.relationships[name].data;
113114
const ret: any[] = [];
114115

115116
relationships.forEach((relationship: any) => {

0 commit comments

Comments
 (0)