Skip to content

Commit

Permalink
#378 Alter touched and error if FA.remove and FA.pop
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredpalmer committed Feb 1, 2018
1 parent 8c7f61a commit b4901a5
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 35 deletions.
116 changes: 85 additions & 31 deletions src/FieldArray.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,53 +56,107 @@ export class FieldArray extends React.Component<FieldArrayConfig, {}> {
formik: PropTypes.object,
};

changeValue = (fn: Function) => {
const { setFieldValue, values } = this.context.formik;
constructor(props: FieldArrayConfig) {
super(props);
// We need TypeScript generics on these, so we'll bind them in the constructor
this.remove = this.remove.bind(this);
this.pop = this.pop.bind(this);
}

updateArrayField = (
fn: Function,
alterTouched: boolean,
alterErrors: boolean
) => {
const {
setFieldTouched,
setFieldValue,
setFieldError,
values,
touched,
errors,
} = this.context.formik;
const { name } = this.props;
const val = fn(dlv(values, name));
setFieldValue(name, val);
setFieldValue(name, fn(dlv(values, name)));

if (alterErrors) {
setFieldError(name, fn(dlv(errors, name)));
}

if (alterTouched) {
setFieldTouched(name, fn(dlv(touched, name)));
}
};

push = (value: any) => this.changeValue((array: any[]) => [...array, value]);
push = (value: any) =>
this.updateArrayField((array: any[]) => [...array, value], false, false);

swap = (indexA: number, indexB: number) =>
this.changeValue((array: any[]) => swap(array, indexA, indexB));
this.updateArrayField(
(array: any[]) => swap(array, indexA, indexB),
false,
false
);

move = (from: number, to: number) =>
this.changeValue((array: any[]) => move(array, from, to));
this.updateArrayField(
(array: any[]) => move(array, from, to),
false,
false
);

insert = (index: number, value: any) =>
this.changeValue((array: any[]) => insert(array, index, value));
this.updateArrayField(
(array: any[]) => insert(array, index, value),
false,
false
);

unshift = (value: any) => {
let arr = [];
this.changeValue((array: any[]) => {
arr = array ? [value, ...array] : [value];
return arr;
});
this.updateArrayField(
(array: any[]) => {
arr = array ? [value, ...array] : [value];
return arr;
},
false,
false
);
return arr.length;
};

remove = (index: number) => {
let result;
this.changeValue((array: any[]) => {
const copy = [...(array || [])];
result = copy[index];
copy.splice(index, 1);
return copy;
});
return result;
};
remove<T>(index: number): T {
// We need to make sure we also remove relevant pieces of `touched` and `errors`
let result: any = [];
this.updateArrayField(
(array: any[]) => {
const copy = [...(array || [])];
// this gets call three times
result.push(copy[index]);
copy.splice(index, 1);
return copy;
},
true,
true
);

return result[0];
}

pop = () => {
let result;
this.changeValue((array: any[]) => {
const tmp = array;
result = tmp.pop();
return tmp;
});
return result;
};
pop<T>(): T {
// We need to make sure we also remove relevant pieces of `touched` and `errors`
let results: any = [];
this.updateArrayField(
(array: any[]) => {
const tmp = array;
results.push(tmp.pop());
return tmp;
},
true,
true
);
return results[0];
}

render() {
const arrayHelpers: ArrayHelpers = {
Expand Down
5 changes: 1 addition & 4 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,7 @@ export function setNestedObjectValues<T>(
if (isObject(val)) {
if (!visited.get(val)) {
visited.set(val, true);
// In order to keep array values consistent for both dot path and
// bracket syntax, we need to check if this is an array so that
// this will output { friends: [true] } and not { friends: { "0": true } }
response[k] = Array.isArray(val) ? [] : {};
response[k] = {};
setNestedObjectValues(val, value, visited, response[k]);
}
} else {
Expand Down

0 comments on commit b4901a5

Please sign in to comment.