@ngneat/reactive-forms
Version:
(Angular Reactive) Forms with Benefits
51 lines • 9.07 kB
JavaScript
import { filter, pairwise, startWith, map } from 'rxjs/operators';
const toArray = (object) => Object.keys(object);
const isArray = (value) => value && Array.isArray(value);
const isObject = (value) => typeof value === 'object' && value !== null;
const isFormArray = (prev, curr) => isArray(curr) || isArray(prev);
const isFormGroup = (prev, curr) => isObject(curr) || isObject(prev);
const isFormControl = (prev, curr) => !isFormArray(prev, curr) && !isFormGroup(prev, curr);
const convertTypesToArray = (left, right) => [left, right];
/**
* An operator which is used to filter valueChanges$ output, that it would emit only changed parts.
*
* @return {MonoTypeOperatorFunction} An Observable that emits items from the source Observable with only changed values.
*/
export function diff() {
return (source$) => source$.pipe(startWith(undefined), pairwise(), map(control => reduceControlValue(...control)), filter(control => control !== undefined));
}
function reduceControlValue(prev, curr) {
if (prev === undefined) {
return curr;
}
if (isFormControl(prev, curr)) {
return prev === curr ? undefined : curr;
}
if (isFormArray(prev, curr)) {
const [left, right] = convertTypesToArray(prev, curr);
return compareArraysContent(left, right) ? undefined : curr;
}
return compareFormGroup(prev, curr);
}
function compareFormGroup(prev, curr) {
const reduced = reduceFormGroup(prev, curr);
return toArray(reduced).length === 0 ? undefined : reduced;
}
function reduceFormGroup(prev, curr) {
if (!prev) {
return curr;
}
return toArray(curr).reduce((acc, key) => {
const control = reduceControlValue(prev[key], curr[key]);
if (control !== undefined) {
acc[key] = control;
}
return acc;
}, {});
}
function compareArraysContent(left, right) {
left = Array.isArray(left) ? left : [];
right = Array.isArray(right) ? right : [];
return left.length === right.length && left.every(value => right.includes(value));
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlmZi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvcmVhY3RpdmUtZm9ybXMvc3JjL2xpYi9vcGVyYXRvcnMvZGlmZi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFbEUsTUFBTSxPQUFPLEdBQUcsQ0FBQyxNQUF3QixFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ2xFLE1BQU0sT0FBTyxHQUFHLENBQUMsS0FBVSxFQUFXLEVBQUUsQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN2RSxNQUFNLFFBQVEsR0FBRyxDQUFDLEtBQVUsRUFBVyxFQUFFLENBQUMsT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssS0FBSyxJQUFJLENBQUM7QUFDdEYsTUFBTSxXQUFXLEdBQUcsQ0FBQyxJQUFTLEVBQUUsSUFBUyxFQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3RGLE1BQU0sV0FBVyxHQUFHLENBQUMsSUFBUyxFQUFFLElBQVMsRUFBVyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN4RixNQUFNLGFBQWEsR0FBRyxDQUFDLElBQVMsRUFBRSxJQUFTLEVBQVcsRUFBRSxDQUFDLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDOUcsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLElBQVMsRUFBRSxLQUFVLEVBQWEsRUFBRSxDQUFDLENBQUUsSUFBc0Is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bGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGZpbHRlciwgcGFpcndpc2UsIHN0YXJ0V2l0aCwgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5jb25zdCB0b0FycmF5ID0gKG9iamVjdDogUmVjb3JkPGFueSwgYW55PikgPT4gT2JqZWN0LmtleXMob2JqZWN0KTtcbmNvbnN0IGlzQXJyYXkgPSAodmFsdWU6IGFueSk6IGJvb2xlYW4gPT4gdmFsdWUgJiYgQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG5jb25zdCBpc09iamVjdCA9ICh2YWx1ZTogYW55KTogYm9vbGVhbiA9PiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsO1xuY29uc3QgaXNGb3JtQXJyYXkgPSAocHJldjogYW55LCBjdXJyOiBhbnkpOiBib29sZWFuID0+IGlzQXJyYXkoY3VycikgfHwgaXNBcnJheShwcmV2KTtcbmNvbnN0IGlzRm9ybUdyb3VwID0gKHByZXY6IGFueSwgY3VycjogYW55KTogYm9vbGVhbiA9PiBpc09iamVjdChjdXJyKSB8fCBpc09iamVjdChwcmV2KTtcbmNvbnN0IGlzRm9ybUNvbnRyb2wgPSAocHJldjogYW55LCBjdXJyOiBhbnkpOiBib29sZWFuID0+ICFpc0Zvcm1BcnJheShwcmV2LCBjdXJyKSAmJiAhaXNGb3JtR3JvdXAocHJldiwgY3Vycik7XG5jb25zdCBjb252ZXJ0VHlwZXNUb0FycmF5ID0gKGxlZnQ6IGFueSwgcmlnaHQ6IGFueSk6IEFycmF5PFtdPiA9PiBbKGxlZnQgYXMgdW5rbm93bikgYXMgW10sIChyaWdodCBhcyB1bmtub3duKSBhcyBbXV07XG5cbi8qKlxuICogQW4gb3BlcmF0b3Igd2hpY2ggaXMgdXNlZCB0byBmaWx0ZXIgdmFsdWVDaGFuZ2VzJCBvdXRwdXQsIHRoYXQgaXQgd291bGQgZW1pdCBvbmx5IGNoYW5nZWQgcGFydHMuXG4gKiBcbiAqIEByZXR1cm4ge01vbm9UeXBlT3BlcmF0b3JGdW5jdGlvbn0gQW4gT2JzZXJ2YWJsZSB0aGF0IGVtaXRzIGl0ZW1zIGZyb20gdGhlIHNvdXJjZSBPYnNlcnZhYmxlIHdpdGggb25seSBjaGFuZ2VkIHZhbHVlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpZmY8VD4oKTogTW9ub1R5cGVPcGVyYXRvckZ1bmN0aW9uPFQgfCB1bmRlZmluZWQ+IHtcbiAgcmV0dXJuIChzb3VyY2UkOiBPYnNlcnZhYmxlPFQgfCB1bmRlZmluZWQ+KSA9PlxuICAgIHNvdXJjZSQucGlwZShcbiAgICAgIHN0YXJ0V2l0aCh1bmRlZmluZWQpLFxuICAgICAgcGFpcndpc2UoKSxcbiAgICAgIG1hcChjb250cm9sID0+IHJlZHVjZUNvbnRyb2xWYWx1ZTxUPiguLi5jb250cm9sKSksXG4gICAgICBmaWx0ZXIoY29udHJvbCA9PiBjb250cm9sICE9PSB1bmRlZmluZWQpXG4gICAgKVxufVxuXG5mdW5jdGlvbiByZWR1Y2VDb250cm9sVmFsdWU8VD4ocHJldjogVCB8IHVuZGVmaW5lZCwgY3VycjogVCB8IHVuZGVmaW5lZCk6IFQgfCB1bmRlZmluZWQge1xuICBpZiAocHJldiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGN1cnI7XG4gIH1cblxuICBpZiAoaXNGb3JtQ29udHJvbChwcmV2LCBjdXJyKSkge1xuICAgIHJldHVybiBwcmV2ID09PSBjdXJyID8gdW5kZWZpbmVkIDogY3VycjtcbiAgfVxuXG4gIGlmIChpc0Zvcm1BcnJheShwcmV2LCBjdXJyKSkge1xuICAgIGNvbnN0IFtsZWZ0LCByaWdodF0gPSBjb252ZXJ0VHlwZXNUb0FycmF5KHByZXYsIGN1cnIpO1xuICAgIHJldHVybiBjb21wYXJlQXJyYXlzQ29udGVudChsZWZ0LCByaWdodCkgPyB1bmRlZmluZWQgOiBjdXJyO1xuICB9XG5cbiAgcmV0dXJuIGNvbXBhcmVGb3JtR3JvdXAocHJldiwgY3Vycik7XG59XG5cbmZ1bmN0aW9uIGNvbXBhcmVGb3JtR3JvdXA8VD4ocHJldjogVCwgY3VycjogVCk6IFQgfCB1bmRlZmluZWQge1xuICBjb25zdCByZWR1Y2VkID0gcmVkdWNlRm9ybUdyb3VwKHByZXYsIGN1cnIpO1xuXG4gIHJldHVybiB0b0FycmF5KHJlZHVjZWQpLmxlbmd0aCA9PT0gMCA/IHVuZGVmaW5lZCA6IHJlZHVjZWQ7XG59XG5cbmZ1bmN0aW9uIHJlZHVjZUZvcm1Hcm91cDxUIGV4dGVuZHMgUmVjb3JkPGFueSwgYW55Pj4ocHJldjogVCwgY3VycjogVCk6IFQge1xuICBpZiAoIXByZXYpIHtcbiAgICByZXR1cm4gY3VycjtcbiAgfVxuXG4gIHJldHVybiB0b0FycmF5KGN1cnIpLnJlZHVjZSgoYWNjLCBrZXkpID0+IHtcbiAgICBjb25zdCBjb250cm9sID0gcmVkdWNlQ29udHJvbFZhbHVlKHByZXZba2V5XSwgY3VycltrZXldKTtcbiAgICBpZiAoY29udHJvbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBhY2Nba2V5XSA9IGNvbnRyb2w7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFjYztcbiAgfSwge30gYXMgUmVjb3JkPGFueSwgYW55Pik7XG59XG5cblxuZnVuY3Rpb24gY29tcGFyZUFycmF5c0NvbnRlbnQ8VCBleHRlbmRzIFtdPihsZWZ0OiBULCByaWdodDogVCk6IGJvb2xlYW4ge1xuICBsZWZ0ID0gQXJyYXkuaXNBcnJheShsZWZ0KSA/IGxlZnQgOiAoW10gYXMgVCk7XG4gIHJpZ2h0ID0gQXJyYXkuaXNBcnJheShyaWdodCkgPyByaWdodCA6IChbXSBhcyBUKTtcbiAgcmV0dXJuIGxlZnQubGVuZ3RoID09PSByaWdodC5sZW5ndGggJiYgbGVmdC5ldmVyeSh2YWx1ZSA9PiByaWdodC5pbmNsdWRlcyh2YWx1ZSkpO1xufSJdfQ==