2
const isFieldEmpty = (data) => {
 const newObj = Object.keys(data).map((key) => {
 if (data[key] === '') {
  const tempKey = key;
  key.value = 'N/A';
  return tempKey;
 }

return key;
});

return newObj;
};

It should search for all empty strings in the object then replace with N/A. Above is my attempt, but it's not working correctly.

Expected input:

const input = { a: "foo", b: "bar", c: "", d: "baz", e: ""}

Expected output:

const foobar = { a: "foo", b: "bar", c: "N/A", d: "baz", e: "N/A"} 
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Tom
  • 53
  • 8
  • Can the object have nested objects in it? – ibrahim mahrir Jul 16 '20 at 15:06
  • @ibrahimmahrir yes possibly – Tom Jul 16 '20 at 15:07
  • Do you want to replace strings in those too? – ibrahim mahrir Jul 16 '20 at 15:09
  • @ibrahimmahrir Yes, if found. – Tom Jul 16 '20 at 15:09
  • Note that there are duplicates to this question out there. – Heretic Monkey Jul 16 '20 at 15:09
  • BTW, do you want to create a new object with the empty strings replaced or is it ok to alter the original object? – ibrahim mahrir Jul 16 '20 at 15:10
  • @ibrahimmahrir yes a new object with the previous objects information as well and the replace keys – Tom Jul 16 '20 at 15:13
  • 1
    Does this answer your question? [recursive find and replace in multidimensional javascript object](https://stackoverflow.com/questions/29473526/recursive-find-and-replace-in-multidimensional-javascript-object) – Heretic Monkey Jul 16 '20 at 15:14
  • If your object doesn't contain `undefined` values that you want to keep and doesn't contain methods then the cleanest approach to clone and replace is: `let newObj = JSON.parse(JSON.stringify(oldObj, (key, value) => typeof value === "string" && value === "" ? "N/A" : value));`. Inspired by [this other SO answer](https://stackoverflow.com/a/51513391/9867451) which uses the [`replacer` parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The_replacer_parameter) of `JSON.stringify`. – ibrahim mahrir Jul 16 '20 at 15:21
  • The thing you want to achieve is called a "deep merge" between objects. ES6/ES7 only provide functions for a shallow merge. For a deep merge, you have to write your own or use a library that does it for you. – Jens Ingels Jul 16 '20 at 15:24

4 Answers4

1

The map operator you are using could be employed if you want a completely new object. If that is the case though, you would have to deal with cloning the original object. Deep cloning with JS objects can be tricky though if your object has nested objects or arrays as a part of it. If you don't need a completely new object, then updating the properties in place on the original object could be done fairly easily as below.

const input = { a: "foo", b: "bar", c: "", d: "baz", e: ""}

Object.keys(input).forEach(key => input[key] = input[key] ? input[key] : 'N/A');
console.log(input);
peinearydevelopment
  • 11,042
  • 5
  • 48
  • 76
  • 1
    will this handle nested objects? – Tom Jul 16 '20 at 15:08
  • 1
    It's always better to *explain* an answer rather than merely post code. This makes the content more valuable not only to the OP but future readers. – Mitya Jul 16 '20 at 15:08
  • @Tom No this won't handle nested objects, but that wasn't a part of your question(unless I missed it). – peinearydevelopment Jul 16 '20 at 15:10
  • @peinearydevelopment oh sorry, I thought that was assumed. Is it possible to handle either or? – Tom Jul 16 '20 at 15:10
  • @Tom is it possible to have string arrays in the object as well? If so, how would you want to handle those? Also, do you need a new object with the `'N/A'` values or is it alright to replace the strings in the original object as in the example above? – peinearydevelopment Jul 16 '20 at 15:11
  • No string arrays. Replacing is fine. – Tom Jul 16 '20 at 15:14
1

const input = {
  a: "foo",
  b: "bar",
  c: "",
  d: "baz",
  e: "",
  f: {
    g: "",
    h: "bfoo"
  }
};

function NAReplacer(obj) {
  return Object.fromEntries(Object.entries(obj).map(([key, value]) => {
    if (typeof value === 'string') {
      return [key, value == '' ? 'N/A' : value];
    }
    if (Object.prototype.toString.call(value) === '[object Object]') {
      return [key, NAReplacer(value)];
    }
  }));
}


console.log(NAReplacer(input));
Sivakumar Tadisetti
  • 4,865
  • 7
  • 34
  • 56
1

Just loop over the keys of the object

const isFieldEmpty = (data) => {
  const newObj = { ...data };
  Object.keys(newObj).forEach((i) => {
    if (newObj[i] === "") {
      newObj[i] = "N/A";
    }
  });
  return newObj;
};

const input = { a: "foo", b: "bar", c: "", d: "baz", e: "" };

console.log(input);
// { a: "foo", b: "bar", c: "", d: "baz", e: "" }
console.log(isFieldEmpty(input));
// { a: "foo", b: "bar", c: "N/A", d: "baz", e: "N/A" }
GeeGeeks
  • 77
  • 2
  • 9
0

Your solution was almost there. From your code key.value = 'N/A';

It's not the key.value that you want to change but data[keys] = 'N/A';

ladder
  • 189
  • 2
  • 9