0

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?

9
  • 1
    "types"[1] is the string "y", so str.hasOwnProperty("types"[1]) is equivalent to str.hasOwnProperty("y") Commented Oct 11, 2024 at 15:52
  • This looks like a job for optional chaining: str?.types?.[1] Commented Oct 11, 2024 at 15:55
  • "Here's the link to JSON data for an example pokémon with 1 types:": I see a structure that has 2 types? Is this a typo? Commented Oct 11, 2024 at 16:10
  • Thanks for taking a look at my issue! When I'm absolutely sure that the syntax must be str.types[1].type.name I shouldn't need optional chaining, right? I just don't know how to write str.types[1].type.name as prop in .hasOwnProperty() when str.hasOwnProperty(types[1].type.name) is impossible Commented Oct 11, 2024 at 16:11
  • @trincot yes, that was a typo (and I can't correct it, too late) Commented Oct 11, 2024 at 16:12

3 Answers 3

1

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".

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

1 Comment

You may need only str.types[1]?.type.name even (with a single optional chaining operator)
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) {
 // ..
}

Comments

0

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);
        }

// Last name encountered:        
        console.log("Last Name found: " + data.types[data.types.length-1].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);
        }
 
// Last name encountered:        
        console.log("Last Name found: " + data.types[data.types.length-1].type.name);

Comments

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.