Skip to content

Commit 1aa1f45

Browse files
committed
feat(Object): Add diffObj Pipe
1 parent 578e8d4 commit 1aa1f45

File tree

7 files changed

+97
-5
lines changed

7 files changed

+97
-5
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
- [omit](#omit)
5555
- [invert](#invert)
5656
- [invertBy](#invertby)
57+
- [diffObj](#diffobj)
5758
- [Math](#math)
5859
- [min](#min)
5960
- [max](#max)
@@ -771,6 +772,19 @@ this.cb = (value): string => {
771772
<p>{{ {a: 1, b: 2, c: 1, d: 2} | invertBy }}</p> <!-- Output: "{1: ['a', 'c'], 2: ['b', 'd']}" -->
772773
```
773774

775+
### diffObj
776+
777+
Returns a diff object of two objects
778+
779+
**Usage:** `object | diffObj: Object`
780+
781+
```html
782+
<p>{{ {a: 1} | diffObj: {a: 1} }}</p> <!-- Output: "{}" -->
783+
<p>{{ {a: 1} | diffObj: {a: 2} }}</p> <!-- Output: "{a: 1}" -->
784+
<p>{{ {a: 1, b: 2} | diffObj: {a: 1, b: 1} }}</p> <!-- Output: "{b: 2}" -->
785+
<p>{{ {a: 1, b: 2, c: {d: 3} } | diffObj: {a: 1, b: 1, c: {d: 1} } }}</p> <!-- Output: "{b: 2, c: {d: 3}}" -->
786+
```
787+
774788
## Math
775789

776790
### min

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ngx-pipes",
3-
"version": "1.4.5",
3+
"version": "1.4.6",
44
"author": "Dan Revah",
55
"description": "Useful angular2 pipes",
66
"license": "MIT",

src/app/pipes/helpers/helpers.spec.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
import {extractDeepPropertyByMapKey} from './helpers';
2+
import {extractDeepPropertyByMapKey, isDeepEqual} from './helpers';
33

44
describe('Utils Tests', () => {
55

@@ -32,4 +32,14 @@ describe('Utils Tests', () => {
3232
expect(extractDeepPropertyByMapKey(obj, 'f.i.j.k.l')).toEqual(6);
3333
expect(extractDeepPropertyByMapKey(obj, 'f.i.j.k.l.')).toEqual(undefined);
3434
});
35+
36+
it('should deep equal properly', () => {
37+
expect(isDeepEqual({a: 1}, {a: 1})).toBeTruthy();
38+
expect(isDeepEqual({a: 1}, {b: 1})).toBeFalsy();
39+
expect(isDeepEqual({a: 1}, {a: 1, b: 1})).toBeFalsy();
40+
expect(isDeepEqual({a: 1, b: 2}, {a: 1, b: 2})).toBeTruthy();
41+
expect(isDeepEqual({a: 1, b: 2}, {a: 1, b: 1})).toBeFalsy();
42+
expect(isDeepEqual({a: 1, b: 2, c: {d: 3}}, {a: 1, b: 2, c: {d: 1}})).toBeFalsy();
43+
expect(isDeepEqual({a: 1, b: 2, c: {d: 3}}, {a: 1, b: 2, c: {d: 3}})).toBeTruthy();
44+
});
3545
});

src/app/pipes/helpers/helpers.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,24 @@ export function extractDeepPropertyByMapKey(obj: any, map: string): any {
3838
: undefined;
3939
}, obj[key || '']);
4040
}
41+
42+
export function getKeysTwoObjects(obj: any, other: any): any {
43+
return [...Object.keys(obj), ...Object.keys(other)]
44+
.filter((key, index, array) => array.indexOf(key) === index);
45+
}
46+
47+
export function isDeepEqual(obj: any, other: any): any {
48+
if (!isObject(obj) || !isObject(other)) {
49+
return obj === other;
50+
}
51+
52+
return getKeysTwoObjects(obj, other).every((key: any): boolean => {
53+
if (!isObject(obj[key]) && !isObject(other[key])) {
54+
return obj[key] === other[key];
55+
}
56+
if (!isObject(obj[key]) || !isObject(other[key])) {
57+
return false;
58+
}
59+
return isDeepEqual(obj[key], other[key]);
60+
});
61+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import {DiffObjPipe} from './diff-obj';
2+
3+
describe('DiffObj Pipe', () => {
4+
let pipe: DiffObjPipe;
5+
6+
beforeEach(() => {
7+
pipe = new DiffObjPipe();
8+
});
9+
10+
it('should keep the element the same way if its not an object', () => {
11+
expect(pipe.transform([1, 2, 3], {})).toEqual({});
12+
expect(pipe.transform([], {})).toEqual({});
13+
expect(pipe.transform('foo', {})).toEqual({});
14+
expect(pipe.transform(null, {})).toEqual({});
15+
expect(pipe.transform(undefined, {})).toEqual({});
16+
});
17+
18+
it('should return an empty object when there is no difference', () => {
19+
expect(pipe.transform({}, {})).toEqual({});
20+
expect(pipe.transform({a: 1}, {a: 1})).toEqual({});
21+
expect(pipe.transform({a: {b: 1}, c: 3}, {a: {b: 1}, c: 3})).toEqual({});
22+
});
23+
24+
it('should return a diff object', () => {
25+
expect(pipe.transform({a: 1}, {a: 2})).toEqual({a: 1});
26+
expect(pipe.transform({a: 1, b: 1}, {a: 1, b: 2})).toEqual({b: 1});
27+
expect(pipe.transform({a: 1, b: true}, {a: 1, b: 2})).toEqual({b: true});
28+
expect(pipe.transform({a: 1, b: {c: 1}}, {a: 1, b: {c: 2}})).toEqual({b: {c: 1}});
29+
});
30+
});

src/app/pipes/object/diff-obj.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import {PipeTransform, Pipe} from '@angular/core';
2+
import {isObject, getKeysTwoObjects, isDeepEqual} from '../helpers/helpers';
3+
4+
@Pipe({name: 'diffObj'})
5+
export class DiffObjPipe implements PipeTransform {
6+
7+
transform(obj: any, original: any = {}): any {
8+
if (Array.isArray(obj) || Array.isArray(original) || !isObject(obj) || !isObject(original)) {
9+
return {};
10+
}
11+
12+
return getKeysTwoObjects(obj, original).reduce((diff: any, key: any) => {
13+
return (!isDeepEqual(original[key], obj[key]) ? diff[key] = obj[key] : {}), diff;
14+
}, {});
15+
}
16+
}

src/app/pipes/object/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@ import {PickPipe} from './pick';
55
import {OmitPipe} from './omit';
66
import {InvertPipe} from './invert';
77
import {InvertByPipe} from './invert-by';
8+
import {DiffObjPipe} from './diff-obj';
89
import {NgModule} from '@angular/core';
910

1011
const OBJECT_PIPES = [
1112
KeysPipe, ValuesPipe, PairsPipe, PickPipe, InvertPipe, InvertByPipe,
12-
OmitPipe
13+
OmitPipe, DiffObjPipe
1314
];
1415

1516
@NgModule({
1617
declarations: OBJECT_PIPES,
1718
imports: [],
1819
exports: OBJECT_PIPES
1920
})
20-
export class NgObjectPipesModule {
21-
}
21+
export class NgObjectPipesModule {}
2222

2323
export {KeysPipe} from './keys';
2424
export {ValuesPipe} from './values';
@@ -27,3 +27,4 @@ export {PickPipe} from './pick';
2727
export {OmitPipe} from './omit';
2828
export {InvertPipe} from './invert';
2929
export {InvertByPipe} from './invert-by';
30+
export {DiffObjPipe} from './diff-obj';

0 commit comments

Comments
 (0)