Nullndr
Nullndr

Reputation: 1827

Check if all fields in a json are set and non null

I have a json like this

{
  "serial": "34AS9831",
  "sensor_type": "Foo",

  "value_registered": {
      "value_type": "temperature",
      "value": 34.6,
      "unit_of_measure": "celsius"
  },

  "value_registered_at": "24/08/2021 14:05:34"
}

I need to check if all fields are set, and they must be non null.

The first solution is the follow:

try {
    check_request(req, res);

    let data = JSON.parse(req.body);

    let isJSONBadFormatted =
      data.serial                           == undefined ||
      data.serial                           == null ||
      data.sensor_type                      == undefined ||
      data.sensor_type                      == null ||
      data.value_registered                 == undefined ||
      data.value_registered                 == null ||
      data.value_registered.value_type      == undefined ||
      data.value_registered.value_type      == null ||
      data.value_registered.value           == undefined ||
      data.value_registered.value           == null ||
      data.value_registered.unit_of_measure == undefined ||
      data.value_registered.unit_of_measure == null ||
      data.value_registered_at              == undefined ||
      data.value_registered_at              == null;

    if(isJSONBadFormatted) {
      unprocessable_json(res);
      alert();
      return;
    }

    insertDataIntoDB(data);

  }catch(err){
    /* TODO: implement alert function */
    alert();
  }

But I don't like this way. Is there a solution to write it in a more elegant way?

Upvotes: 4

Views: 2236

Answers (2)

Som Shekhar Mukherjee
Som Shekhar Mukherjee

Reputation: 8168

Solution Using Recursion


Designing The Layout For Fields

  • Create a fields array that contains all the desired properties in the following manner:
    • For properties directly on the object provide them as strings.
    • For nested properties provide an array where the first element is the direct key and the second element is all the keys nested inside.

Working Of Recursive Function

  • Loop through all values in the fields array.
    • If the value is NOT an Array and it is NOT inside the object return false.
    • If it is an Array
      • Check if the first element of the array (which is a string) is present in the object, if NOT return false.
      • If the above condition passes, call checkFields with the correct object and the second element of the array (which is an array itself). Return false if checkFields fails.

NOTE: I've increased the nesting by adding two more fields to value.

const obj = {
  serial: "34AS9831",
  sensor_type: "Foo",
  value_registered: {
    value_type: "temperature",
    value: { record1: 35, record2: 67 },
    unit_of_measure: "celsius",
  },
  value_registered_at: "24/08/2021 14:05:34",
};

const fields = [
  "serial",
  "sensor_type",
  [
    "value_registered",
    ["value_type", ["value", ["record1", "record2"]], "unit_of_measure"],
  ],
  "value_registered_at",
];

const checkField = (obj, fields) => {
  for (let field of fields) {
    if (!Array.isArray(field)) {
      if (obj?.[field] === undefined) return false;
    } else if (!obj?.[field[0]] || !checkField(obj[field[0]], field[1]))
      return false;
  }
  return true;
};

console.log(checkField(obj, fields));

Upvotes: 1

Hao Wu
Hao Wu

Reputation: 20699

You may try this function:

const validate = (obj, validations) => 
  validations.every(key => ![undefined, null].includes(key.split('.').reduce((acc, cur) => acc?.[cur], obj)));

Just need to provide an array that contains every property name that is not supposed to be empty.

const validate = (obj, validations) => 
  validations.every(key => ![undefined, null].includes(key.split('.').reduce((acc, cur) => acc?.[cur], obj)));

const data = {
  "serial": "34AS9831",
  "sensor_type": "Foo",

  "value_registered": {
      "value_type": "temperature",
      "value": 34.6,
      "unit_of_measure": "celsius"
  },

  "value_registered_at": "24/08/2021 14:05:34"
};

const validations = [
  'serial', 
  'sensor_type', 
  'value_registered', 
  'value_registered.value_type', 
  'value_registered.value', 
  'value_registered.unit_of_measure', 
  'value_registered_at'
];

  
console.log(validate(data, validations));

Upvotes: 3

Related Questions