mojoo
mojoo

Reputation: 77

does object/array exist in javascript

I'm trying to put content from RSS feed - problem is every RSS feed has different formats for images, content etc.

I'm trying to see if certain object exists in javascript or jquery:

item.mediaGroups[0].contents[0].url

How can I check it in an if statement? I keep getting for feeds without this structure:

Uncaught TypeError: Cannot read property '0' of undefined 

Also tried:

if (typeof item.mediaGroups[0].contents[0].url === "undefined")

but I keep getting the same error.

thanks!

Upvotes: 1

Views: 144

Answers (6)

Eva Cohen
Eva Cohen

Reputation: 505

How about 'optional chaining' (described in ES2021 spec and already implemented in all browsers except three) ?

from MDN:

The optional chaining operator provides a way to simplify accessing values through connected objects when it's possible that a reference or function may be undefined or null.

The optional chaining ?. stops the evaluation if the value before ?. is undefined or null and returns undefined so it is giving us a way to handle the possibly undefined/nullsish values

item?.mediaGroups[0]?.contents[0]?.url // will evaluates to undefined if either of those is undefined.

Upvotes: 0

Peppe L-G
Peppe L-G

Reputation: 8345

It's not a solution with if-statements (as requested), but you can use exceptions to achieve similar functionality. Something like this:

function throwOrReturn(thing){

    if(typeof thing === 'undefined'){

        throw "Didn't find it..."

    }else{

        return thing

    }

}

// The unknown thing.
var a = {
    b1: {
    },
    b2: {
        c: 'lookingFor'
    }
}

var c

// Test our different paths.
try{

    // First guess.
    c = throwOrReturn(a.b1.c.d)+" - a.b1.c.d"

}catch(error){

    try{

        // Second guess.
        c = throwOrReturn(a.b[45][34].c)+" - a.b[45][34].c"

    }catch(error){

        try{

            // Third guess.
            c = throwOrReturn(a.b2.c)+" - a.b2.c"

        }catch(error){

            // Try more guesses, or give up.
            c = "notFound"

        }

    }

}

console.log("c:", c) // Logs: "c: lookingFor - a.b2.c" 

It ain't pretty, but it's an alternative worth to mention.

Upvotes: -1

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276446

There is no "simple" built in way to do this sort of in depth checking. The reasoning is simple - most of the time you know the type of the objects you're working against.

You can do:

if (typeof item !== "undefined" &&
    typeof item.mediaGroups !== "undefined" &&
    typeof item.mediaGroups[0] !== "undefined" &&
    typeof item.megiaGroups[0].contents !== "undefined" &&
    typeof item.megiaGroups[0].contents[0] !== "undefined" &&
    typeof item.mediaGroups[0].contents[0].url !== "undefined"){

When you type all that you might want to consider your data structures, since this really is not a situation you should be in to begin with :)

(hint, you can skip the typeof on all but the first, but I think typeof is a good clarification here).

The real question is this:

Why are you not sure what the structure of your data is?

If you are querying data (for example XML in an RSS feed) there are effective ways to do so with XPATH or query selectors. Object property access is built for objects where what you're querying is a document. Sure, it's possible with a bunch of ugly checks just like you can hammer a nail in with a heavy screwdriver.

You can see this question in Stack Overflow on how to use DOM methods to parse XML.

Upvotes: 6

TGH
TGH

Reputation: 39268

I would check the length of both arrays in this case to be sure - before assuming there are objects defined at index 0

item.mediaGroups.length > 0

and

item.mediaGroups[0].contents.length > 0

As the outer check you can also throw in a

if(item.mediaGroups){
} 

Upvotes: 1

OneOfOne
OneOfOne

Reputation: 99351

item.mediaGroups[0].contents is undefined, you have to check for it.

if(item.mediaGroups && item.mediaGroups[0].contents) {
    return item.mediaGroups[0].contents[0].url;
}

Upvotes: -1

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324750

If you're uncertain about the exisence of properties, try this helper function:

function getProperty(root) {
    var l = arguments.length, i, undefined;
    for( i=1; i<l; i++) {
        if( typeof root[arguments[i]] == "undefined") return undefined;
        root = root[arguments[i]];
    }
    return root;
}

You can then call it like this:

var url = getProperty(item,'mediaGroups',0,'contents',0,'url');

As a more "haxy" way, you can try this:

try {url = item.mediaGroups[0].contents[0].url;}
catch(e) {url = undefined;}

Upvotes: 1

Related Questions