Home > database >  Render Pokemon double-type weaknesses/resistances in React
Render Pokemon double-type weaknesses/resistances in React

Time:11-14

I'm creating a small component that takes the type(s) of a Pokemon stored in the state (pokemonState.types) as an array of objects for each type, then compare the type(s) to a JSON file containing all the weaknesses/resistances (see below).

Here is what the json looks like:

    "dragon": {
         "half": ["electric", "fire", "grass", "water"],
         "double": ["dragon", "ice", "fairy"],
         "zero": []
     },
     "ground": {
          "half": ["poison", "rock"],
          "double": ["grass", "ice", "water"],
          "zero": ["electric"]
      },

However, I'm struggling a lot to code the render part for Pokemon with double-types. Here is a picture similar to what I want to render (exactly like pokemon websites pretty much):

enter image description here

Note that if both types have a weakness in common, the multiplier displayed is x4 instead of x2. If both types have a resistance in common the multiplier is 0.25 instead of 0.

Here is my code so far that works fine for single-type Pokemon:

 const PokemonChart = () => {
    if (!_.isEmpty(pokemonState)) {
      const listWeaknesses = pokemonState.types.map((item) =>
        types_data[item.type.name].double.map((el) => (
          <p className={`types ${el}`} key={el}>
            {el}
          </p>
        ))
      );
      return (
        <div>
          <h1>Type Effectiveness</h1>
          {listWeaknesses}
        </div>
      );
    }
  };

My first issue, is that when two types share a weakness, this weakness will be listed twice. I tried to merge both type's data together into an array to make it easier, but as they're rendered one after the other it didn't work.

(see below an example with Dragon/Ground type pokemon).

example with Dragon/Ground type pokemon

My question: How can I get rid of duplicates types, but also keep track of them, so that I can render different multipliers. Example: If "ice x2" is rendered twice, returns one "ice x4" instead.

CodePudding user response:

Here ya go :)

const e = React.createElement;
const getPokemon = () => {
    return (
        {   "name": "bulbasaur",
            "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/"
                    }
                }
            ],
            "weight": 69
        }
    );
}
const pokemonState = getPokemon();

let types_data = {
    "grass": {
        "attack": {
            "double": ["ground", "rock", "water"],
            "half": ["flying", "poison", "bug", "steel", "fire", "grass", "dragon" ],
            "zero": []
        },
        "defense": {
            "half": ["ground", "water", "grass", "electric"],
            "double": ["flying", "poison", "bug", "fire", "ice"],
            "zero": []
        }
    },
    "poison": {
        "attack": {
            "double": ["grass", "fairy"],
            "half": ["poison", "ground", "rock", "fairy"],
            "zero": ["steel"]
        },
        "defense": {
            "half": ["fighting", "poison", "bug", "grass", "fairy"],
            "double": ["ground", "psychic"],
            "zero": []
        }
    }
};

const PokemonTypeChart = () => {
    if (!_.isEmpty(pokemonState)) {
        const allTypes = Object.entries(types_data);
        const pokemonType = allTypes.map(([key, value]) => {
            return (pokemonState.types.map((el) => {
                if (el.type.name === key) {
                    return (
                        <p key="{el.type.name}">{el.type.name}</p>
                    );
                }
            }));
        });


        let weaknesses = {};
        pokemonState.types.forEach(item =>{
            let defense = types_data[item.type.name].defense;
            Object.entries(defense).forEach(([key, value]) => {
                switch(key){
                    case('double'):
                        value.forEach(i => {weaknesses[i] ? weaknesses[i] *= 2 : weaknesses[i] = 2});
                        break;
                    case('half'):
                        value.forEach(i => {weaknesses[i] ? weaknesses[i] *= .5 : weaknesses[i] = .5});
                        break;
                    case('zero'):
                        value.forEach(i => {weaknesses[i] = 0});
                        break;
                }
            });
        });

        const weaknessDisplay = [];
        Object.entries(weaknesses).forEach(([key, value]) =>
        {
            weaknessDisplay.push(<li key={key}>{key} - {value}x</li>);
        });
              return (
            <div>
                <h1>{pokemonState.name}</h1>
                <hr />
                <h2>Pokemon Type</h2>
                {pokemonType}
                <hr />
                <h2>Weaknesses</h2>
                {weaknessDisplay}

            </div>
        );
    }};


const domContainer = document.querySelector('#pokemon');
ReactDOM.render(e(PokemonTypeChart), domContainer);
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/underscore-umd-min.js"></script>
    
    <div id="pokemon"></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related