Animal fun facts - can't go through task 10

Hello everyone!
I can’t make my app generate random facts. Actually I have no idea what to do exactly in task 10 of Animal Fun Facts: https://www.codecademy.com/paths/build-web-apps-with-react/tracks/bwa-intro-to-react/modules/react-101-jsx-u/projects/js-react-animal-fun-facts the explanation seems very vague to me, honestly. I have no idea if my solution to task 9 is what they wanted as well. Here’s my code so far:

import { animals } from './animals';
import React from 'react';
import ReactDOM from 'react-dom';

const background = <img 
                      className='background'
                      alt='ocean'
                      src='/images/ocean.jpg' />;
const title = '';
const images = [];

const displayFact = e => {
  return e.facts[Math.floor(Math.random()*e.facts.length)]
}

for(const animal in animals){
  images.push(
    <img
      key={animal}
      className='animal'
      alt={animal}
      src={animals[animal].image}
      ariaLabel={animal}
      role='button'
      onClick={displayFact(animals[animal])}
     />
  )
}
const animalFacts = (
  <div>
  
 <h1>{title === '' ? 'Click an animal for a fun fact' : title }</h1>
 {background}
 <div className='animals'>
  {images}
 </div>
 <p id='fact'>
  {displayFact(animals.dolphin)}
  </p>
   </div>
   )
 ;


ReactDOM.render(animalFacts, document.getElementById('root'))

Thanks in advance for any help or guidance

5 Likes

This is what I did for it. The animal type is being stored in the alt attribute of image, so it can be accessed using e.target.alt. You can then pass that in to the animals array to select the specific animal and its properties (in this case facts). I hope this helps!

function displayFact(e){
let facts = animals[e.target.alt].facts;
let rand = Math.floor(Math.random() * facts.length)
let fact = animals[e.target.alt].facts[rand];
document.getElementById(“fact”).innerHTML = fact;
}

8 Likes

Thanks a lot, that solved my problem too!

Thank you, it really helped! Everything works perfectly and I understand what I missed then.

@chip6821406076 can You please post the complete project code cuz i still wasn’t able to get it right after @tera1236914686’s response too. Thanks.

Remember to have your displayFact function above your animalFacts and where you set the .onclick event :slight_smile:

4 Likes

What value did you send in to the displayFacts function?
the console is giving me an error with the one that I sent in.

Hi

My Code + Bonus Feature Added

Cheers

6 Likes

Why do we need those two console.log’s in displayFact function

it was just for me testing somthing in the console.

I think there is a lot to update in the recently updated react course, the latest updated one has no clear instructions and they weren’t clear like the many projects I have done.

3 Likes

You are totally right. But now i am stuck with it and have to complete it now. :frowning:

1 Like

Thanks Guys So much! Big Help :grinning:

Let me post my code here. Everything works fine now, also the bonus feature (at least in the way I understood it). Here’s the app.js code:

import { animals } from './animals';
import React from 'react';
import ReactDOM from 'react-dom';

const title = '';

const images = [];

for(const animal in animals){
  images.push(<img
    key={animal}
    className='animal'
    alt={animal}
    src={animals[animal].image}
    ariaLabel={animal}
    role='button'
    onClick={displayFact}
    />
  )
}

function displayFact(e){
  const animalFacts = animals[e.target.alt].facts;
  const randomFactsIndex = Math.floor(Math.random()*animalFacts.length)
  document.getElementById('fact').innerHTML = animalFacts[randomFactsIndex]
}

let showBackground = true;

const background = <img 
                      className='background'
                      alt='ocean'
                      src='/images/ocean.jpg'
                       />


const animalFacts =  (
  <div>
    <h1>{title === '' ? 'Click an animal for a fun fact' : title}</h1>
    {(showBackground) && background}
    <div className='animals'>{images}</div>
    <p id='fact'>

    </p>
  </div>
  );


ReactDOM.render(animalFacts, document.getElementById('root'))
2 Likes

This is completely aside… I’m not a big fan of re-purposing the alternate text which is intended for screen readers, not dynamic script. The alternative is to use either the title attribute or one that says what it is… data={animal}. Small concern, but we should remember legacy attributes and not redefine their role.

3 Likes
function displayFact(e){
let facts = animals[e.target.alt].facts;
let rand = Math.floor(Math.random() * facts.length)
let fact = animals[e.target.alt].facts[rand];
document.getElementById(“fact”).innerHTML = fact;
}

Anyway to refactor this event function as an arrow function?
like…

displayFact = (e) => {
...
}

Maybe there’s some big piece of information I am not understanding, but when I refactored this function as an arrow function the onClick event no longer renders. I would greatly appreciate any help in understanding why and how. Thank you!

It wouldn’t be refactoring because that usually refines and dials in the conciseness which an arrow function will not do in this situation. The only thing I would do is make it a function expression rather than a declared function.

const displayFact = function (e) {
    const r = x => Math.floor(Math.random() * x)
    const x = document.querySelector('#fact')
    const a = animals[e.target.data]
    x.textContent = a.facts[r(a.facts.length)]
}

From a purist’s perspective we could say that arrow functions are best used as expressions with implicit returns, else use conventional function syntax. The above doesn’t return anything, hence use of vanilla code. The contained helper function does use concise syntax.

2 Likes

Thanks. I don’t initially understand so it seems I’ll spend some time digesting this.

2 Likes

Even when returning in an arrow function, the random facts still do not render. Why is this and can it work whilst being an arrow function?

const randomIndex = Math.floor(Math.random() *
  animals[e.target.alt].facts.length);
  const randomFact = animals[e.target.alt].facts[randomIndex];
  return document.getElementById('fact').innerHTML = randomFact;
};

another q! if alt and key are the same value of {animal}, why doesn’t e.target.key work?