Reputation: 3
somewhere from the API data I am getting normal string like, “Hi ${person[0].name}” now this string I am converting into template string and getting replace its variables from array of object.
Here is snippet which I am trying to execute, and I am not getting expected output
const getObjPath = (path, obj, fallback = `$\{${path}}`) => {
if (path && obj) return path.split('.').reduce((res, key) => res[key] || fallback, obj);
return path;
};
const interpolate = (template, variables, fallback) => {
const regex = /\${[^{]+}/g;
if (template && variables) {
return template.replace(regex, (match) => {
let path = match.slice(2, -1).trim();
path = path.split('|').map((item) => item.trim());
const fieldValue = getObjPath(path[0], variables, fallback);
if (fieldValue) return fieldValue;
return path[1] || fallback;
});
}
return template;
};
const data = { person: [{ name: 'John', age: 18 }] };
const a = interpolate('Hi ${person?.[0]?.name | text} (${person?.[0]?.age | text})', data);
console.log(a);
output: "Hi ${person?.[0]?.name} (${person?.[0]?.age})"
expected output: "Hi John 18"
Can someone tell me what I am doing wrong here?
Upvotes: 0
Views: 271
Reputation: 350310
The problem is that your path splitting in getObjPath
does not deal with square brackets in the path.
So replace this
path.split('.')
with:
path.match(/[^.[\]]+/g)
const getObjPath = (path, obj, fallback = `$\{${path}}`) => {
if (path && obj) return path.match(/[^.[\]]+/g).reduce((res, key) => res[key] || fallback, obj);
return path;
};
const interpolate = (template, variables, fallback) => {
const regex = /\${[^{]+}/g;
if (template && variables) {
return template.replace(regex, (match) => {
let path = match.slice(2, -1).trim();
path = path.split('|').map((item) => item.trim());
const fieldValue = getObjPath(path[0], variables, fallback);
if (fieldValue) return fieldValue;
return path[1] || fallback;
});
}
return template;
};
const data = { person: [{ name: 'John', age: 18 }] };
const a = interpolate('Hi ${person[0].name | text} (${person[0].age | text})', data);
console.log(a);
Upvotes: 1