N00b having trouble with callbacks

I’m working on exercise 11, and frankly I’m just not getting it. The subject is callbacks.

I was able to write the following code, it works, and I understand how it works:

let calc = (x,y,cb) => cb(x,y)

let add = (x,y) => x+y;
let mult = (x,y)=>x*y;
let sub = (x,y)=>x-y;
let div = (x,y)=>x/y;

console.log(calc(5,8,add));

So I’m not completely lost.

Here is the code I’m struggling with as provided in the lesson:

const fancyPet = (owner_name, owner_age, pet_name, pet_age, cb) => {
    cb(owner_name, owner_age);
    console.log(`That person owns ${pet_name} who is ${pet_age} years old.`);
}

// notice how I use a function here as the parameter cb?
fancyPet('Zed', 44, 'Mr. Scruffles', 10, (name, age) => {
    console.log(`Ooooh fancy ${name} you are ${age} old.`);
});

I understand most of this, except for how it knows that name=Zed and age=44. Its not referenced anywhere else. Its clearly right, because it works.

I was able to restructure it this way, but I can’t convince myself that this is truly a callback:

let petInfo = (owner_name, owner_age, pet_name, pet_age) => {
    console.log(`Your name is ${owner_name}, your age is ${owner_age}, Your pets name is ${pet_name}, and your pets age is ${pet_age}`);
}
console.log(petInfo("Jason",37,"Fezzik",4));

This is a bit different than my calculator above because my console.log was only in one place - outside all functions. In my restructured code the console that is actually executing is from within the function. So I’m passing the correct data in, but if this is truly a callback its not clear to me why I have to use a console log to pass this data.

Thanks for any help you can provide.

Edit: sorry for all the edits. Not too familiar with markdown and took a few tries to make the post look like it needed to

One of our devs just came in … I think I go it now:

1 Like

You have it right there, Jason: cb is a function that takes owner_name and owner_age as parameters.
When you call fancyPet() you give it all the parameters, and as you can see, in place of cb you give it (name, age)
You could have written (monkey, doughnut) instead, it didn’t matter, it’s just a name of the original owner_name, owner_age.
I think this is what confuses you.
But cb is the parameter called last, so whatever you put instead of owner_name, owner_age will call the owner_name and owner_age you defined in FancyPet(‘Zed’, 44…)
See it now?

Yup… very helpful. Thanks io_io!

What I wasn’t getting was that it was based on order. TBH, the following code makes a lot more sense to me:

const fancyPet = (owner_name, owner_age, pet_name, pet_age, cb) => {
    cb(owner_name, owner_age,pet_name,pet_age);
}

fancyPet('Jason', 37, 'Fezzik', 4, (blah, blerg,pfft,zing) => {
    console.log(`Ooooh fancy ${blah} you are ${blerg} years old.  Your pets name is ${pfft} and they are ${zing} years old`);
});

using completely stupid variables helps to understand that it has no relation to what cb is providing… its order.

Also, it certainly wasn’t clear with console logs in two places…

1 Like

regarding ^ I get that you wouldn’t want to use stupid variables in production code… I was just struggling to relate name to owner_name, etc

1 Like

no, it is not based on order, it is based on the name of the original variables.
You could have given cb other variables from that list, like:
cb(owner_age, pet_age, owner_name)
or
cb(owner_age)
You can give cb whatever parameter you need from that list, the order or the number of parameters has nothing to do with it.
When you call it , it’s still the last parameter, and you can replace the original parameters with whatever names.

hmmmm, then I’m not fully understanding this. I appreciate your patience!

so… first I try changing the order of my inputs:

const fancyPet = (owner_name, owner_age,  pet_name, pet_age, cb) => {
    cb(owner_name, owner_age, pet_name, pet_age);
}
fancyPet(37, 'Jason', 'Fezzik', 4, (blah, blerg,pfft,zing) => {
    console.log(`Name: ${blah} // Age: ${blerg} yrs // Pets name: ${pfft} // Pet age: ${zing} years`);
});

I get a result of:

Name: 37 // Age: Jason yrs // Pets name: Fezzik // Pet age: 4 years

so, now I change that back, and change the order in the function:

const fancyPet = (owner_name, pet_name, owner_age, pet_age, cb) => {
    cb(owner_name, owner_age, pet_name, pet_age);
}
fancyPet('Jason', 37, 'Fezzik', 4, (blah, blerg,pfft,zing) => {
    console.log(`Name: ${blah} // Age: ${blerg} yrs // Pets name: ${pfft} // Pet age: ${zing} years`);
});

and I get this result:

Name: Jason // Age: Fezzik yrs // Pets name: 37 // Pet age: 4 years

ok, so now I change the order in the cb statement:

const fancyPet = (owner_name, owner_age,  pet_name, pet_age, cb) => {
    cb(owner_name, pet_name, owner_age, pet_age);
}
fancyPet('Jason', 37, 'Fezzik', 4, (blah, blerg,pfft,zing) => {
    console.log(`Name: ${blah} // Age: ${blerg} yrs // Pets name: ${pfft} // Pet age: ${zing} years`);
});

and get this:

Name: Jason // Age: Fezzik yrs // Pets name: 37 // Pet age: 4 years

Finally, I change the order of my variables:

const fancyPet = (owner_name, owner_age,  pet_name, pet_age, cb) => {
    cb(owner_name, owner_age, pet_name, pet_age);
}
fancyPet('Jason', 37, 'Fezzik', 4, (blah, blerg,zing, pfft) => {
    console.log(`Name: ${blah} // Age: ${blerg} yrs // Pets name: ${pfft} // Pet age: ${zing} years`);
});

and get this:

Name: Jason // Age: 37 yrs // Pets name: 4 // Pet age: Fezzik years

I’m not getting how its not based on order, but I’m sure I’m just missing something…

Thanks!

I meant the order of parameters when you define cb is not important.
Sure, when you call it you have to put the name in the name parameter etc, but you can call it like:
console.log('Age: ${blerg}, Name:c{blah}')
So when you give cb the parameters, right before the arrow function, you need to always associate in your mind owner_name with blah, etc, so you respect that order.
Wherever you see the blah, you know it’s the owner_name, wherever you see zing, you know it’s the pet_name.
See it?

Yup… got it! Thanks for the help!

1 Like

Sorry, I wasn’t clear from the beginning, glad you got it.

Nice, I’m glad @io_io could help you out @JasonF. I’ll be sure to do that mapping in the video. Actually I remember doing that but I see there isn’t a video for 11 yet so I’m probably just imagining I did it.

1 Like

Thanks Zed…

I’m able to see the video for 11, but its the last video I can see. Are there any more to publish? :wink:

I should be getting videos up soon. I decided to get the writing done for exercises all the way to 30 so I can get the first half of the book done then crank out all the videos.

In an effort to understand this in ex 11 I have added some log comments.

The order of the displays is baffling. I have looked into the following subjects for an explanation (I am going to continue on in hopes this comes to me eventually:)
hoisting, overriding, const creation, and order or precedence.

I was even wondering if there is an issue between Javascript and node.js itself as it is an interpreter.

Note: JavaScript supports overriding not overloading.

image

Shawn

References

I think what might be confusing is the logging style you’re using. Try this:

console.log(">>>>> calling cb", owner_name, owner_age);
cb(owner_name, owner_age);
console.log("<<<<< exit cb", owner_name, owner_age);

You can then use the >>> and <<< indicators to show when you enter and exit each function, and use the number of < or > to give you an idea of depth. So, you might do this:

console.log(">>> fancyPet");

When you enter fancyPet, then do console.log("<<< fancyPet"); when you exit it.

1 Like

This was super useful. Stole it for future reference :joy: I was having similar trouble, went over the exercise again and mostly understood it but this really solidified my understanding. Thanks.

1 Like