0

I have got an object, that may look like this:

{
  address: {
    street: undefined,
    country: 'GB'
  },
  givenname: 'Marko',
  surname: null,
}

I want to know if all fields are set or if at least one is null. Is there a smarter / shorter way to dot his in javascript than

address.street != null && address.country != null && givenname != null && surname != null

Maybe something that looks like this:

// this could return true or false?
nullCheck(address.street, address.country, givenname, surname)
6
  • You don't have to explicitly check against != null. You can rely on implicit conversion to Boolean and a truthy check: if(address.streetl && address.country && givenname && surname) Commented Jul 23, 2020 at 12:39
  • @ScottMarcus but empty strings will not pass this check. Commented Jul 23, 2020 at 12:40
  • Your title is kind of misleading, since there are no consts in your code. Your property names are also invalid. Commented Jul 23, 2020 at 12:40
  • 1
    Does this answer your question? Determining if all attributes on a javascript object are null or an empty string Commented Jul 23, 2020 at 12:41
  • The given object is not valid. The . cannot by used in JavaScript identifiers. Do you mean { "address.street": undefined, "address.country": 'GB' } or { address: { street: undefined, country: 'GB' } }? Commented Jul 23, 2020 at 12:42

4 Answers 4

2

Yes, there is. You can use the Object data type, and the includes array method like this:

Object.values(your_object).includes(null)

This will return true if your object contains at least one null element and false if it doesn't contain any.

This answer only works for 1 level deep objects.

Object Documentation Array.includes Documentation

Sign up to request clarification or add additional context in comments.

Comments

2

You can use the every method, given a list of variables to check, with a callback that checks for null.

let address = {
    street: undefined,
    country: 'GB'
  },
  givenname = 'Marko',
  surname = null;

console.log([address.street, address.country, givenname, surname].every(e => e !== null))

surname = "blah"

console.log([address.street, address.country, givenname, surname].every(e => e !== null))

Comments

1

The first one is the typical way to go actually. Works fine specially if you have typings, like with TypeScript.

The second one is just the same but with a bit of overhead (each time you enter/exit a function, adss a bit of overhead), although is really small overhead only noticeable when you have tons of iterations. You can detect the arguments dynamically:

const nullobj = {
    value1: "yay",
    value2: "",
    value3: 23,
    value4: null
};
const obj = {
    value1: "yay",
    value2: "",
    value3: 23,
    value4: "ok"
};

function checkArgumentsNull(...args) {
    for (let v of args) {
        if (v == null) {
            return true;
        }
    }
    return false;
}

console.log("nullobj:", checkArgumentsNull(nullobj.value1, nullobj.value2, nullobj.value3, nullobj.value4));
console.log("obj:", checkArgumentsNull(obj.value1, obj.value2, obj.value3, obj.value4));

But if you are going to check dynamically for arguments, you can check dynamically for properties, which is easier. Just saw your edit and this one can be easily converted to a recursive one that will check for sub-objects. Actually all functions here can be converted to recursive ones following this principle:

const nullobj = {
    value1: {
        ok: "ok",
        notok: null
    },
    value2: "",
    value3: 23,
    value4: "ok"
};
const obj = {
    value1: {
        ok: "ok",
        notok: "no"
    },
    value2: "",
    value3: 23,
    value4: "ok"
};

function checkPropertiesNull(obj) {
    for (let v in obj) {
        if (obj[v] == null || (typeof obj[v] === "object" && checkPropertiesNull(obj[v]))) {
            return true;
        }
    }
    return false;
}

console.log("nullobj:", checkPropertiesNull(nullobj));
console.log("obj:", checkPropertiesNull(obj));

And for the sake of modern JavaScript, you can even pass an iterator, and you can check whatever iterable object you can imagine of (object, arrays, maps, sets, etc):

const nullobj = {
    value1: "yay",
    value2: "",
    value3: 23,
    value4: null
};
const obj = {
    value1: "yay",
    value2: "",
    value3: 23,
    value4: "ok"
};
const nullarr = ["ok", "yay", null];
const arr = ["ok", "yay", "yay2"];

function checkIteratorNull(it) {
    for (let v of it) {
        if (v == null) {
            return true;
        }
    }
    return false;
}

console.log("nullobj:", checkIteratorNull(Object.values(nullobj)));
console.log("obj:", checkIteratorNull(Object.values(obj)));
console.log("nullarr:", checkIteratorNull(nullarr));
console.log("arr:", checkIteratorNull(arr));

Comments

1

You can use .some

const hasAnEmptyValue = (obj) => Object.values(obj).some(value => !value)

const obj1 = {
  address: null,
  givenname: 'Rick',
  surname: 'Sanchez',
}

const obj2 = {
  address: 'Argentina',
  givenname: 'Rick',
  surname: 'Sanchez',
}
    
console.log(hasAnEmptyValue(obj1))

console.log(hasAnEmptyValue(obj2))

2 Comments

I'm curious. Why !Boolean(value) and not simply !value. Is there any moment where they return different values? Just to know.
@JorgeFuentesGonzález yeah, should be the same. I was using Boolean because at first I was doing: .some(Boolean) but then I changed to return !Boolean

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.