Skip to content

Instantly share code, notes, and snippets.

@imAliAzhar
Last active June 30, 2021 17:30
Show Gist options
  • Save imAliAzhar/0f68fcba4d7fdca02052e52758a68e15 to your computer and use it in GitHub Desktop.
Save imAliAzhar/0f68fcba4d7fdca02052e52758a68e15 to your computer and use it in GitHub Desktop.
A succint funtion that transforms JS Object to using a declarative schema
// Code
export const pickDeep = (obj: Dict<any>, key: string) =>
hasKey(obj, key) ? obj[key] : key.split(".").reduce((o, k) => o?.[k], obj);
export const transform = (from: Dict<any>, to: Dict<any>) =>
keys(to).reduce((o: Dict<any>, k) => {
const t = to[k]; // for each key that we want in the new object, get the transformer
o[k] = Array.isArray(t) // check if the transformer is an array
? typeof last(t) === "object" // if so, check if the last element of the transformer array is another 'to' object
? pickDeep(from, t[0]).map((i: Dict<any>) => transform(i, last(t))) // if so, apply this 'to' transformation to the array pointed in the first element of the transformer array
: last(t)(...t.slice(0, -1).map((u) => pickDeep(from, u))) // otherwise last element must be a function, pass it the values pointed in the transformer array
: isObject(t) // if transformer is another object
? transform(from, t) // recursively apply transform
: typeof t === "string" // if its a string
? pickDeep(from, t) // pick the deep value
: t; // otherwise just store the passed value as it is in the transformed object
return o;
}, {});
// Usage
const source = {
user: {
id: 1,
first_name: "Ali",
last_name: "Azhar",
role: {
id: 1,
title: "Software Engineer",
},
},
};
const transformer = {
user: {
// combine multiple values from source object
name: ["user.first_name", "user.last_name", (firstName: string, lastName: string) => `${firstName} ${lastName}`],
},
role: "role.title",
};
// Another example
{
id: "id",
text: "question.text",
shortText: "question.text_short",
options: [
"available_options", // transformation schema for an item within the list `available_options`
{
id: "id",
text: "text",
subOptions: [
"sub_options", // transformation schema for an item within the list `sub_options`
{
id: "id",
text: "text",
subOptions: "sub_options",
},
],
},
],
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment