Skip to content
This repository has been archived by the owner on Mar 20, 2022. It is now read-only.

Commit

Permalink
Compat: Ensure undefined/null values are filtered out
Browse files Browse the repository at this point in the history
  • Loading branch information
paularmstrong committed Dec 27, 2016
1 parent c1cb330 commit 5c98122
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/schemas/Array.js
Expand Up @@ -23,6 +23,7 @@ export default class ArraySchema extends PolymorphicSchema {
normalize(input, parent, key, visit, addEntity) {
const values = Array.isArray(input) ? input : Object.values(input);

return values.map((value, index) => this.normalizeValue(value, parent, key, visit, addEntity));
return values.map((value, index) => this.normalizeValue(value, parent, key, visit, addEntity))
.filter((value) => value !== undefined && value !== null);
}
}
7 changes: 6 additions & 1 deletion src/schemas/Object.js
Expand Up @@ -2,7 +2,12 @@ export const normalize = (schema, input, parent, key, visit, addEntity) => {
const object = { ...input };
Object.keys(schema).forEach((key) => {
const localSchema = schema[key];
object[key] = visit(input[key], input, key, localSchema, addEntity);
const value = visit(input[key], input, key, localSchema, addEntity);
if (value === undefined || value === null) {
delete object[key];

This comment has been minimized.

Copy link
@bsara

bsara Mar 28, 2018

Contributor

@paularmstrong I'm curious as to the reason that one would want undefined and null values ignored?

I have a schema similar to the following:

cosnt simpleItemSchema = new schema.Entity('simpleItems');

const complexItemSchema = new schema.Entity('complexItems', {
  nested: {
    simpleItem: simpleItemSchema
  },
  ...
});

Now, nested.simpleItem will sometimes be null; and it being null has some special significance because it means that it was specifically set to null. However, the property is omitted from the normalization of any "complexItem". This creates a problem due to the fact that null has meaning here and if the property is not present, one cannot assume that the value might be null or undefined. (I'm doing some diffing and whatnot, hence the need for the presence of the property).

Would it be reasonable to want to add an option to not omit null values or to not omit the null value so long as the schema of the property is an EntitySchema? (this would be because an EntitySchema do not omit null and undefined properties and it may be useful to know when something that is expected to be an entity is null or undefined)

} else {
object[key] = value;
}
});
return object;
};
Expand Down
2 changes: 1 addition & 1 deletion src/schemas/Polymorphic.js
Expand Up @@ -36,7 +36,7 @@ export default class PolymorphicSchema {
normalizeValue(value, parent, key, visit, addEntity) {
const schema = this.inferSchema(value, parent, key);
const normalizedValue = visit(value, parent, key, schema, addEntity);
return this.isSingleSchema ?
return this.isSingleSchema || normalizedValue === undefined || normalizedValue === null ?
normalizedValue :
{ id: normalizedValue, schema: this.getSchemaAttribute(value, parent, key) };
}
Expand Down
4 changes: 2 additions & 2 deletions src/schemas/Values.js
Expand Up @@ -4,10 +4,10 @@ export default class ValuesSchema extends PolymorphicSchema {
normalize(input, parent, key, visit, addEntity) {
return Object.keys(input).reduce((output, key, index) => {
const value = input[key];
return {
return value !== undefined && value !== null ? {
...output,
[key]: this.normalizeValue(value, input, key, visit, addEntity)
};
} : output;
}, {});
}
}
6 changes: 6 additions & 0 deletions src/schemas/__tests__/Array.test.js
Expand Up @@ -65,5 +65,11 @@ describe(schema.Array.name, () => {
const users = new schema.Array(userSchema);
expect(normalize({ foo: { id: 1 }, bar: { id: 2 } }, users)).toMatchSnapshot();
});

it('filters out undefined and null normalized values', () => {
const userSchema = new schema.Entity('user');
const users = new schema.Array(userSchema);
expect(normalize([ undefined, { id: 123 }, null ], users)).toMatchSnapshot();
});
});
});
6 changes: 6 additions & 0 deletions src/schemas/__tests__/Object.test.js
Expand Up @@ -14,4 +14,10 @@ describe(schema.Object.name, () => {
const userSchema = new schema.Entity('user');
expect(normalize({ user: { id: 1 } }, { user: userSchema })).toMatchSnapshot();
});

it('filters out undefined and null values', () => {
const userSchema = new schema.Entity('user');
const users = { foo: userSchema, bar: userSchema, baz: userSchema };
expect(normalize({ foo: {}, bar: { id: '1' } }, users)).toMatchSnapshot();
});
});
15 changes: 15 additions & 0 deletions src/schemas/__tests__/Values.test.js
Expand Up @@ -38,4 +38,19 @@ describe(schema.Values.name, () => {

expect(() => normalize({ fluffy: { id: 1, type: 'cat' } }, valuesSchema)).toThrow();
});

it('filters out null and undefined values', () => {
const cat = new schema.Entity('cats');
const dog = new schema.Entity('dogs');
const valuesSchema = new schema.Values({
dogs: dog,
cats: cat
}, (entity, key) => entity.type);

expect(normalize({
fido: undefined,
milo: null,
fluffy: { id: 1, type: 'cats' }
}, valuesSchema)).toMatchSnapshot();
});
});
15 changes: 15 additions & 0 deletions src/schemas/__tests__/__snapshots__/Array.test.js.snap
@@ -1,3 +1,18 @@
exports[`ArraySchema Class filters out undefined and null normalized values 1`] = `
Object {
"entities": Object {
"user": Object {
"123": Object {
"id": 123,
},
},
},
"result": Array [
123,
],
}
`;

exports[`ArraySchema Class normalizes Objects using their values 1`] = `
Object {
"entities": Object {
Expand Down
16 changes: 16 additions & 0 deletions src/schemas/__tests__/__snapshots__/Object.test.js.snap
@@ -1,3 +1,19 @@
exports[`ObjectSchema filters out undefined and null values 1`] = `
Object {
"entities": Object {
"user": Object {
"1": Object {
"id": "1",
},
"undefined": Object {},
},
},
"result": Object {
"bar": "1",
},
}
`;

exports[`ObjectSchema normalizes an object 1`] = `
Object {
"entities": Object {
Expand Down
19 changes: 19 additions & 0 deletions src/schemas/__tests__/__snapshots__/Values.test.js.snap
Expand Up @@ -27,6 +27,25 @@ Object {
}
`;

exports[`ValuesSchema filters out null and undefined values 1`] = `
Object {
"entities": Object {
"cats": Object {
"1": Object {
"id": 1,
"type": "cats",
},
},
},
"result": Object {
"fluffy": Object {
"id": 1,
"schema": "cats",
},
},
}
`;

exports[`ValuesSchema normalizes the values of an object with the given schema 1`] = `
Object {
"entities": Object {
Expand Down

0 comments on commit 5c98122

Please sign in to comment.