Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript Displaying the Content

Michael Rushton
Michael Rushton
7,123 Points

Why do we pass the function the parameter (data) and not (data.message) - why do we pass a parameter at all?

Im really struggling to understand why after saying that the fulfilled promise from the second .then (response.json) is going to be called data and then use an arrow function to create a function that has arguments (data.message) but then when we go to actually say what that function will do (below) why do we only put (data) as the argument? not (data.message). i don't understand why we put (data) in the generateImage function or any parameter as id have thought when the function is called by the .then part it would populate the function with the appropriate (data.message) arguments in order to locate the correct part of the returned json. It's been driving me crazy since last night. Please someone help my poor brain!!😂😂

2 Answers

Brandon White
seal-mask
MOD
.a{fill-rule:evenodd;}techdegree seal-36
Brandon White
Treehouse Moderator

Hi Michael Rushton,

I'm going to do my best to explain this. And it may help your understanding to reverse the process that Guil describes. So instead of starting with the fetch request, how about we start with an idea.

We want to write a function that will generate an image. The way the function works is that we will create an html string and we will set it as the value of a card element's innerHTML.

Because we're trying to create an image, we know our html string will need to include an <img> tag, and we know that image tag will need a src and alt attribute. The src attribute will be set to the value of the url path of the image. Now we could hard code the url path of the image into the <img> tag's src attribute like this: <img src="../my_image". But if we did that, our function wouldn't be very dynamic.

So instead, let's use a placeholder as the url path of the image. To do that we'll add a parameter to our function that will serve as a variable. Let's name that variable urlPath. So now our html string looks something like this: <img src="${urlPath}". And since we're using a parameter within the body of our function which as a whole looks like this:

function generateImage() {
    const html = `
        <img src='${urlPath}' alt>
        <p>Click to view images of ${select.value}s</p>
    `;
    card.innerHTML = html
}

We need to except a parameter in the first line of the function. Like this:

function generateImage(urlPath) {
    const html = `
        <img src='${urlPath}' alt>
        <p>Click to view images of ${select.value}s</p>
    `;
    card.innerHTML = html
}

Now that we have our function, let's send a fetch request to an API.

fetch('https://dog.ceo/api/breeds/image/random') // <= this returns a json res which we pass as an arg into the first then func 
    .then(response => response.json()) // <= this takes that json res and converts it into a js object which we pass an arg into the next json func
    .then(data => generateImage(data.message)) // now we pass the js object as an arg into the generateImage func
// But the js object has multiple key/value pairs
// Perhaps that object looks something like this:
/*
 {
   dogType: "Jack Chi",
   description: "A Jack Chi digging a hole",
   year: 2017,
   message: "https://dog.ceo/images/37iq63hoja"
 }
*/
// Well our generateImage function doesn't need the entire object to work; it only needs the url path of the image
// So instead of passing the entire object, we just pass the object's message property (ie. data.message)

Had Guil written the generateImage function first, he likely would have named the parameter I named "urlPath" something other than data; but because he wrote it after he'd already written the fetch request and chained the then methods to it, he knew he would be passing an argument named data into the function, and so he named the parameter data so they would match up

Hopefully, that makes sense. If not, let me know; I'll try again.

Michael Rushton
Michael Rushton
7,123 Points

Brandon.... Oh my gosh!! Thank you so much for giving such a detailed answer! Thats so kind of you! I have only just seen this so i'm going to go and read it in detail and get my head around it all but thanks so much, what an absolute legend! Such a kind thing to help me out like that! Really made my day that has.