Determining if all attributes on a javascript object are null or an empty string
Asked Answered
O

21

112

What is the most elegant way to determine if all attributes in a javascript object are either null or the empty string? It should work for an arbitrary number of attributes.

{'a':null, 'b':''} //should return true for this object
{'a':1, 'b':''} //should return false for this object
{'a':0, 'b':1} //should return false
{'a':'', 'b':''} //should return true
Orography answered 30/12, 2014 at 17:14 Comment(1)
No matter what, you'll have to loop through all the elements in the object and check each one.Olszewski
C
81

Create a function to loop and check:

function checkProperties(obj) {
    for (var key in obj) {
        if (obj[key] !== null && obj[key] != "")
            return false;
    }
    return true;
}

var obj = {
    x: null,
    y: "",
    z: 1
}

checkProperties(obj) //returns false
Colotomy answered 30/12, 2014 at 17:16 Comment(1)
@ J-Bob: This or adeneo's answer should get you started. If you also want to allow undefined, change the === null to == null. And you may or may not want to add a hasOwnProperty check, depending on whether you care about properties from prototypes. (adeneo's answer only checks "own" properties, tymeJV's does both "own" and prototype). Or perhaps a check ignoring properties referring to functions (again, if desired).Gonfalon
L
199

Check all values with Object.values. It returns an array with the values, which you can check with Array.prototype.every or Array.prototype.some:

const isEmpty = Object.values(object).every(x => x === null || x === '');
const isEmpty = !Object.values(object).some(x => x !== null && x !== '');
Lovesome answered 22/3, 2018 at 11:32 Comment(4)
or shorter: Object.values(object).every(x => !!x);Borate
@JonathanMeguira This is not what the OP is asking for. Checking for falsy includes way more then an empty string or null.Lovesome
@abd995 That’s not correct. some and every are equally efficient and equally fast. They both implement short-circuit evaluation: as soon as some hits a value for which the condition doesn’t hold, the iteration stops, yes, but the same thing applies to every.Lauryn
array.some(Boolean) & array.every(Boolean) excels here, too. (be mindful of 0's though).Betoken
C
81

Create a function to loop and check:

function checkProperties(obj) {
    for (var key in obj) {
        if (obj[key] !== null && obj[key] != "")
            return false;
    }
    return true;
}

var obj = {
    x: null,
    y: "",
    z: 1
}

checkProperties(obj) //returns false
Colotomy answered 30/12, 2014 at 17:16 Comment(1)
@ J-Bob: This or adeneo's answer should get you started. If you also want to allow undefined, change the === null to == null. And you may or may not want to add a hasOwnProperty check, depending on whether you care about properties from prototypes. (adeneo's answer only checks "own" properties, tymeJV's does both "own" and prototype). Or perhaps a check ignoring properties referring to functions (again, if desired).Gonfalon
B
30

Here's my version, specifically checking for null and empty strings (would be easier to just check for falsy)

function isEmptyObject(o) {
    return Object.keys(o).every(function(x) {
        return o[x]===''||o[x]===null;  // or just "return o[x];" for falsy values
    });
}
Bagnio answered 30/12, 2014 at 17:21 Comment(0)
O
14
let obj = { x: null, y: "hello", z: 1 };
let obj1 = { x: null, y: "", z: 0 };

!Object.values(obj).some(v => v);
// false

!Object.values(obj1).some(v => v);
// true
Orbicular answered 23/5, 2020 at 14:36 Comment(1)
While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value.Cultism
E
10

Quick and simple solution:

Object.values(object).every(value => !!value);
Epigeous answered 30/11, 2021 at 3:6 Comment(2)
{'a':'', 'b':''} will return false. OP want return trueNagari
This does not work when the array is like {'a':'', 'b': null, e: undefined}. I have to use ["", undefined, null].every(value => !value); Ingres
P
9

Using Array.some() and check if the values are not null and not empty is more efficient than using Array.every and check it the other way around.

const isEmpty = !Object.values(object).some(x => (x !== null && x !== ''));

This answer should just make the excellent comment of user abd995 more visible.

Perish answered 6/11, 2019 at 9:40 Comment(1)
That comment is wrong, though. Both methods are equally efficient.Lauryn
M
6

You can use the Array.reduce prototype on your object's keys.

Assuming that the object is structured as follows:

var obj = {
    x: null,
    y: "",
    z: 1
}

you can use the following instruction to discover if all of it's properties are unset or set to empty string using just one line:

Object.keys(obj).reduce((res, k) => res && !(!!obj[k] || obj[k] === false || !isNaN(parseInt(obj[k]))), true) // returns false

If you want to discover if all of it's properties are set instead you have to remove the negation before the conditions and set the initial result value to true only if the object has keys:

Object.keys(obj).reduce((res, k) => res && (!!obj[k] || obj[k] === false || !isNaN(parseInt(obj[k]))), Object.keys(obj).length > 0) // returns false as well
Magulac answered 24/10, 2017 at 16:59 Comment(0)
C
5

Based on adeneo's answer, I created a single line condition. Hope it will be helpful to someone.

var test = {
  "email": "[email protected]",
  "phone": "1234567890",
  "name": "Test",
  "mobile": "9876543210",
  "address": {
      "street": "",
      "city": "",
      "state": "",
      "country": "",
      "postalcode": "r"
  },
  "website": "www.test.com"
};

if (Object.keys(test.address).every(function(x) { return test.address[x]===''||test.address[x]===null;}) === false) {
   console.log('has something');
} else {
   console.log('nothing');
}

You can test it https://jsfiddle.net/4uyue8tk/2/

Casandracasanova answered 8/6, 2017 at 8:44 Comment(0)
M
5

Just complementing the past answers: they'll work if your object doesn't contain arrays or objects. If it does, you'll need to do a 'deep check'.

So I came up with this solution. It'll evaluate the object as empty if all its values (and values inside values) are undefined, {} or [].

function deepCheckEmptyObject(obj) {
    return Object.values(obj).every( value => {
        if (value === undefined) return true;
        else if ((value instanceof Array || value instanceof Object) && _.isEmpty(value) ) return true;
        else if (value instanceof Array && !_.isEmpty(value)) return deepCheckEmptyArray(value);
        else if (value instanceof Object && !_.isEmpty(value)) return deepCheckEmptyObject(value);
        else return false;
    });
}

function deepCheckEmptyArray(array) {
    return array.every( value => {
        if (value === undefined) return true;
        else if ((value instanceof Array || value instanceof Object) && _.isEmpty(value)) return true;
        else if (value instanceof Array && !_.isEmpty(value)) return deepCheckEmptyArray(value);
        else if (value instanceof Object && !_.isEmpty(value)) return deepCheckEmptyObject(value);
        else return false;
    });
}

Note it uses Lodash's .isEmpty() to do the heavy work after we 'isolated' a value. Here, Lodash is imported as '_'.

Hope it helps!

Magnet answered 5/2, 2019 at 19:43 Comment(0)
S
4

Also if you are searching for only values are empty within the object,

Object.values({ key: 0, key2: null, key3: undefined, key4: '' }).some(e => Boolean(e))
// false

Object.values({ key: 0, key2: null, key3: undefined, key4: "hello" }).some(e => Boolean(e))
// true

Object.values({ key: 1, key2: "hello" }).some(e => Boolean(e))
// true
Spun answered 23/4, 2020 at 9:22 Comment(0)
V
2

Based on tymeJv's answer =)

function checkProperties(obj) {
var state = true;
  for (var key in obj) {
    if ( !( obj[key] === null || obj[key] === "" ) ) {
        state = false;
        break;
    }
  }
  return state;
}

var obj = {
  x: null,
  y: "",
  z: 1
}

checkProperties(obj) //returns false

Hope it helps =)

Veliz answered 30/12, 2014 at 17:31 Comment(0)
H
2

This will give you all the keys from the object which is empty, undefined and null

Object.keys(obj).filter((k)=> {
  if (obj[k] === "" || obj[k]===undefined || obj[k]===null) {
    return k;
  }
});
Huehuebner answered 17/5, 2019 at 9:39 Comment(0)
N
1

Building on top of other answers I would use lodash to check isEmpty on the object, as well as its properties.

const isEmpty = (object) => return _.isEmpty(object) || !Object.values(object).some(x => !_.isEmpty(x))
Norwich answered 15/2, 2019 at 14:30 Comment(0)
C
0

This skip the function attribute

function checkIsNull(obj){
		let isNull=true;
		for(let key in obj){
			if (obj[key] && typeof obj[key] !== 'function') {
				isNull = false;
			}
		}
		return isNull;
	}

var objectWithFunctionEmpty={
  "name":undefined,
  "surname":null,
  "fun": function (){ alert('ciao'); }
}

var objectWithFunctionFull={
  "name":undefined,
  "surname":"bla bla",
  "fun": function (){ alert('ciao'); }
}

checkIsNull(objectWithFunctionEmpty); //true
checkIsNull(objectWithFunctionFull); //false
Clavier answered 16/6, 2018 at 11:2 Comment(0)
P
0

This works with me perfectly:

checkProperties(obj) {
  let arr = [];
  for (let key in obj) {
    arr.push(obj[key] !== undefined && obj[key] !== null && obj[key] !== "");
  }
  return arr.includes(false);
}

This will return true or false if there is at-least one value is empty or something like that.

Phonetician answered 18/8, 2019 at 20:54 Comment(0)
D
0

You can use Object.values() method to get all the object's values (as an array of object's values) and then check if this array of values contains null or "" values, with the help of _.includes method prvided by lodash library.

const checkObjectProperties = obj => {
  const objValues = Object.keys(obj);

  if (_.includes(objValues, "") || _.includes(objValues, null)) {
    return false;
  } else {
    return true
  }
  
  const incorrectObjProps = { one: null, two: "", three: 78 }
  const correctObjProps = { one: "some string" }
  
  checkObjectProperties(incorrectObjProps) // return false
  checkObjectProperties(correctObjProps) // return true
}
Dulin answered 10/9, 2019 at 12:28 Comment(0)
A
0

I'll add my two sense:

Object.values(object).every(value => Boolean(value));
Amphi answered 9/6, 2021 at 15:9 Comment(1)
this wont allow whitespaces also => var stateIsValid = Object.values(this.state).every((value) => Boolean(String(value).trim()))Audrit
S
0

Solution:

function checkValues(obj) {
  var objValues = Object.values(obj);
  if (objValues.length < 1) return false;
  return objValues.every((value) => {
    if (value === null) return true;
    if (typeof(value) == 'string')
      if(!(value || false))
        return true;
    return false;
  });
}
// OR
Object.values( obj ).every(
  value => value === null || (typeof(value) == 'string' && !(value || false))
);

Testing:

checkValues({ a: null, b: '' });
// OR
Object.values({ a: null, b: '' }).every(
  value => value === null || (typeof(value) == 'string' && !(value || false))
);
// Output: true

checkValues({ a: '', b: '' });
// OR
Object.values({ a: '', b: '' }).every(
  value => value === null || (typeof(value) == 'string' && !(value || false))
);
// Output: true

checkValues({ a: 0, b: '' });
// OR
Object.values({ a: 0, b: '' }).every(
  value => value === null || (typeof(value) == 'string' && !(value || false))
)
// Output: false

checkValues({ a: 0, b: 1 });
// OR
Object.values({ a: 0, b: 1 }).every(
  value => value === null || (typeof(value) == 'string' && !(value || false))
)
// Output: false

checkValues({ a: 1, b: '' });
// OR
Object.values({ a: 1, b: '' }).every(
  value => value === null || (typeof(value) == 'string' && !(value || false))
)
// Output: false
Shiny answered 16/8, 2021 at 20:54 Comment(0)
S
0

You can use the Object.values() method to get all of the object's values (as an array of object's values) and then check if this array of values contains null or "", with the help of methods provided by the lodash library.

Subtemperate answered 13/6, 2023 at 13:23 Comment(0)
I
0

Consider that you have the following object

obj = {'a':'', 'b': null, e: undefined}

The function to check object has empty value for all keys

const isEmptyObj = (obj) => {
    return Object.values(obj).every(val => !val); 
}

Now the function call isEmptyObj(obj) will return true.

Let us consider another object

obj1 = {'a':'', 'b': null, e: undefined, f: 21}

The function call isEmptyObj(obj1) will return false.

Ingres answered 22/1, 2024 at 12:42 Comment(0)
D
-1

How about this?

!Object.values(yourObject).join('')
Detruncate answered 17/8, 2021 at 21:6 Comment(1)
pro tip: you can add code fences to format the codeEternal

© 2022 - 2025 — McMap. All rights reserved.