How to check more than one level of an object without the code being visually ugly?

Asked

Viewed 76 times

-1

I have an object postCardImage it is filled by a return that I have in my API, the problem is that I need to test the whole object that returned to then assign it.

I take the test like this:

postCardImage:
  post._embedded["wp:featuredmedia"] |
  post._embedded["wp:featuredmedia"][0] |
  post._embedded["wp:featuredmedia"][0].media_details |
  post._embedded["wp:featuredmedia"][0].media_details.sizes |
  post._embedded["wp:featuredmedia"][0].media_details.sizes.full |
  post._embedded["wp:featuredmedia"][0].media_details.sizes.full.source_url ? post._embedded["wp:featuredmedia"][0].media_details.sizes.full.source_url : ""

however I found it very big and ugly, I wondered if it would not have a more elegant way of testing that?

for example:

 if(post._embedded["wp:featuredmedia"][0].media_details.sizes.full.source_url){
  console.log("objeto ok");
 }

This is a very common problem in my daily life, but I have not yet found a solution. What needs to be done to improve this question?

1 answer

2


You can create a function for this:

function get(obj, path) {
    const attributes = path.split('.');

    for (let attribute of attributes) {
        if (!obj.hasOwnProperty(attribute)) {
            return null;
        }

        obj = obj[attribute];
    }

    return obj;
}

It basically traverses the path of attributes you want and if any of them do not exist returns null. Weaknesses of this solution is that if the desired value is null you won’t be able to tell if you returned the value correctly or if you returned null because it did not find the attribute; another is that since the dot character is used as separator, none of the attributes can have it in the name (this can be circumvented by changing the separator to another character).

function get(obj, path) {
    const attributes = path.split('.');

    for (let attribute of attributes) {
        if (!obj.hasOwnProperty(attribute)) {
            return null;
        }

        obj = obj[attribute];
    }

    return obj;
}

const obj = {
    _embedded: {
        "wp:featuredmedia": [
            {
                media_details: {
                    sizes: {
                        full: {
                            source_url: 'Conteudo'
                        }
                    }
                }
            }
        ]
    }
};

const existe = get(obj, '_embedded.wp:featuredmedia.0.media_details.sizes.full.source_url');
const naoExiste = get(obj, '_embedded.wp:featuredmedia.1.media_details.sizes.full.source_url');

console.log(existe, naoExiste);

  • 2

    Good answer. Other ideas that occurred to me were the ?. which is in Stage 1 in the TC39 suggestions. And another would be to have a try/catch but that does not make the code more beautiful and can hide other mistakes... +1

Browser other questions tagged

You are not signed in. Login or sign up in order to post.