skip to Main Content

I’m currently building a Pokémon application, therefor I’m accessing data from PokéAPI and will store specific data in a variable, such as name, id and type.

Currently I’m facing issues to store the second type of a pokémon. Some of them have one type, some of them have two.

If a pokémon has two types the data structure looks like this:
Bulbasaur JSON data screenshot from pokeapi.co/api/v2/pokemon/bulbasaur

Here’s the link to JSON data for an example pokémon with 1 types: https://pokeapi.co/api/v2/pokemon/bulbasaur

If a pokémon only has one type the structure looks like this:
Togepi JSON data screenshot from https://pokeapi.co/api/v2/pokemon/togepi

Link: https://pokeapi.co/api/v2/pokemon/togepi

To check whether there’s a second type or not I wrote a function:

function CheckPropertySecondtype(str) {
  if (str.hasOwnProperty("types"[1])) {
    pokemondata.secondtype = str.types[1].type.name;
    console.log("Pokemon has a second type");
  } else {
    pokemondata.secondtype = "none";
    console.log(str.types[1].type.name);
  }
}

The problem is, that the if statement doesn’t work the way I want it to. It’s always false which means no matter if there’s a second type or not, the output is always "none". I tried several notations like hasOwnProperty(types[1].type.name) or hasOwnProperty(types1.type.name).

How can I access the key correctly to check this?

3

Answers


  1. As others have mentioned in the comments, str.hasOwnProperty("types"[1])is equivalent to str.hasOwnProperty("y"), which should be false. One option is to split it into two conditions:

    if (str.hasOwnProperty("types") && str.types.hasOwnProperty(1)) {
     // ...
    }
    

    (note that the second condition could be rewritten as str.types.length >= 1). If str does not have a types property, the expression will short circuit and so the check for str.types[1] will never run (so won’t error).

    Or, you could write it more simply using optional chaining:

    if (str.types?.[0] !== undefined) {
     // ..
    }
    
    Login or Signup to reply.
  2. You don’t need the if...else construct here. With the operators ?. (optional chaining) and ?? (nullish coalescing), you can do it in a single assignment:

    pokemondata.secondtype = str.types[1]?.type?.name ?? "none";
    

    This works because the name property is assumed to be a string, and so if str.types[1]?.type?.name is undefined, we know for sure it wasn’t present, and so the ?? expression will evaluate to "none".

    Login or Signup to reply.
  3. As an alternative, you can check the length of types in the JSON.

    // shortened JSON data for the first URL:       
            var strJSON1= '{"types": [{"slot": 1, "type": {"name": "fairy", "url": "https://pokeapi.co/api/v2/type/18/"}}]}' ;
    
            var data= JSON.parse(strJSON1);
    
            console.log("*****URL-1******");
    
            console.log('Count of types: ' + data.types.length);
    
            for (var i=0; i<data.types.length; i++){
                console.log("Name" + (i+1) +": " + data.types[i].type.name);
            }
        
    
    // shortened JSON data for the second URL:
            var strJSON2= '{"types": [{"slot": 1,"type": {"name": "grass","url": "https://pokeapi.co/api/v2/type/12/"}},{"slot": 2,"type": {"name": "poison","url": "https://pokeapi.co/api/v2/type/4/"}}]}' ;
     
            var data= JSON.parse(strJSON2);
    
            console.log("*****URL-2******");
    
    
            console.log('Count of types: ' + data.types.length); 
            for (var i=0; i<data.types.length; i++){
                console.log("Name" + (i+1) +": " + data.types[i].type.name);
            }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search