1

Beginner in javascript so please bear with me.

I'm trying to create a program that will check an object for any null, empty or undefined values. It seems to be working fine for most part, but when there is an array in the object, it shows it as "empty items" when it is populated.

Could someone show me how to alter my code so that it checks if arrays are truly empty?

My code is as follows:

const myObj = 
  {  "tags": ["A", "B", "C"],
    "shared_with": ["abc", "123"],
    "list": [],
    "public_jobs": true,
    "config": null,
    "id": 9406,
    "name": "",
  }

const removeNotEmpty = (obj) => {
  Object.keys(obj).forEach(k => {//for each property of the object
      if(typeof obj[k] === 'object' && obj[k] !== null){//if the property is an object
          removeNotEmpty(obj[k]);//recurse
    }else if(obj[k]){//if property is truthy
      delete obj[k];//remove it from the object
    }else if(obj[k] == !obj.length){
      delete obj[k];
    }
  });
  return obj;
};

// make sure to copy the object if you don't want to modify the first 
// (that's what the Object.assign is for)
console.log(removeNotEmpty(Object.assign({},myObj)));

Thanks in advance.

EDIT: So I've incorporated some edits into my codes based on the suggestions below and this is my code now

const myObj = 
  {  "tags": ["A", "B", "C"],
    "shared_with": ["abc", "123"],
    "list": [],
    "public_jobs": true,
    "config": null,
    "id": 9406,
    "name": "",
  }

const removeNotEmpty = (obj) => {
  Object.keys(obj).forEach(k => {//for each property of the object
      if(Object.prototype.toString.call(obj[k]) === '[object Array]'){
        delete obj[k];
    }else if(typeof obj[k] === 'object' && obj[k] !== null){//if the property         
IS an object
          removeNotEmpty(obj[k]);//recurse)
    }else if(obj[k]){//if property is truthy
      delete obj[k];//remove it from the object
    }
  });
  return obj;
};

console.log(removeNotEmpty(Object.assign({},myObj)));//make sure to copy the     
object if you don't want to modify the first (that's what the Object.assign 
is for)

The problem now is that it does not display empty arrays, such as the "list: []" ? Any ideas people?

7
  • 1
    In your outer call, you use Object.assign to "copy the object as you don't want to modify it". In the recursive calls, you ignore that though. Commented Dec 6, 2018 at 12:48
  • What is this suppose to do obj[k] == !obj.length? This will never return true even for arrays. Commented Dec 6, 2018 at 12:54
  • I'm a beginner, literally, was just trying different things but couldn't figure it out Commented Dec 6, 2018 at 12:56
  • I can't figure it out what you are trying to achieve. What should your function removeNotEmpty do? Commented Dec 6, 2018 at 12:57
  • Basically, it should navigate the object and check for any "null", "undefined" or empty values. It should then display only the values that are empty. Commented Dec 6, 2018 at 12:58

3 Answers 3

2

Because in JS, Array IS AN OBJECT.

So, "tags": ["A", "B", "C"] will go to the first If clause. Because it's an object and also not null. And if you iterate an array with Object.keys it will return the indexes as Keys.

So, you need a condition to check if the key is an array or not. which can be done by

Array.isArray(obj[k])

or

Object.prototype.toString.call(obj[k]) === '[object Array]';

Edit: Leisurely adding it to the first if clause.

Object.keys(obj).forEach(k => {
    if(Object.prototype.toString.call(obj[k]) === '[object Array]' && obj[k].length >0 ){
    //delete stuff
    }else if(...//remaining code
    .
    .
    .
});
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, could you please show me how i can add this into my specific code because i keep getting errors.
Everything is an object in JS, the whole idea of typeof operator is so it gives you what kind of object :) Typeof operator is one of the IMHO mayor retardations of JS, it's inconsistent garbage. Prototype is uglier in syntax but more consistent. Like try typeof NaN. It literally gives "number" on something that is supposed to represent NOT A NUMBER! Also typeof null gives you "object". That makes sense, what kind of object is this, typeof operator? Oh it's just a plain regular object dear dev. Dumpster level of operator!
Hey, I tried your code out and it works. But for some reason it does not display empty arrays such as "list: []" any ideas how this can be fixed?
just add && obj[k].length > 0 in my if clause.
0

Read through it 3 times I still have no idea what you're trying to achieve but if the problem is detecting empty arrays (only empty ones not ones filled with undefined or nulls) then this will work:

Array.isArray(suspectingThisIsArray) && suspectingThisIsArray.length == 0

This checks if suspecting object is an array and then short-circuits if it is not. If it is it checks whether it is empty. If it's empty the whole expression is true.

Is this what you desire to detect?

Comments

0

Looks like you're looking for falsy values or empty arrays.

Object.entries(myObj).forEach(([k, v]) => {
    if (!v || (Array.isArray(v) && v.length === 0)) {
        console.log(`${k} is falsy or an empty array`)
    }
})

3 Comments

The other conditionals are flaky also
Thanks for your answer, just wondering how would I use this in my code? I just put it in my code and it says array not defined.
It's Array with a capital A.

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.