FAQ: Code Challenges: Intermediate JavaScript - shoutGreetings()

This community-built FAQ covers the “shoutGreetings()” exercise from the lesson “Code Challenges: Intermediate JavaScript”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Web Development

FAQs on the exercise shoutGreetings()

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head here.

Looking for motivation to keep learning? Join our wider discussions.

Learn more about how to use this guide.

Found a bug? Report it!

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

Why is this solution not being accepted?

// Write your code here:
const newArr = [];

const shoutGreetings = (arr) => {
  arr.forEach(function(element) {
    newArr.push(element.toUpperCase() + "!");	
  });
  return newArr;
}


// Feel free to uncomment out the code below to test your function!

const greetings = ['hello', 'hi', 'heya', 'oi', 'hey', 'yo'];

console.log(shoutGreetings(greetings));
/*
Should print [ 'HELLO!', 'HI!', 'HEYA!', 'OI!', 'HEY!', 'YO!' ]
*/

because when you call the function for a second time:

const greetings = ['hello', 'hi', 'heya', 'oi', 'hey', 'yo'];

console.log(shoutGreetings(greetings));

cont example = ['just', 'to', 'prove', 'my', 'point'];

console.log(shoutGreetings(example));

things don’t go well, or at least not as expected.

I think what @stetim94 is pointing out is that the array is defined outside of the function so does not reset each call. It will just keep growing. That is not something we want to have happen. Declare data structures inside the function so they start fresh every call.

Another thing to consider, the name of the function is, shoutGreetings, not getGreetings so we would necessarily expect a return value. Only that the function will log out the greetings.

arr.forEach(x => console.log(x.toUpperCase());
return 0;
3 Likes

This is accepted:

const shoutGreetings = arr => {
  const newArr = [];
  	arr.map(element => {
  	newArr.push(element.toUpperCase().concat('!'));
  })
  return newArr;
}

const greetings = ['hello', 'hi', 'heya', 'oi', 'hey', 'yo'];
console.log(shoutGreetings(greetings))

The code below however is not, while it should be accepted:

const shoutGreetings = arr => {
  const newArr = [];
  	arr.map(element => {
  	newArr.push(element.toUpperCase().concat('!'));
  })
  return console.log(newArr);
}

const greetings = ['hello', 'hi', 'heya', 'oi', 'hey', 'yo'];
shoutGreetings(greetings)

They both log out the same on the console, yet only the above code is accepted as correct.
I believe this to be a bug!?

2 Likes

no, its not a bug. Now another developer takes over your project, calls your function (second example), he expects an array, yet he gets undefined (the log method returns undefined, thus, so does your function)

Thank you for replying.
Both pieces of code are logging out: ["HELLO!", "HI!", "HEYA!", "OI!", "HEY!", "YO!"] in the console.

I’m not getting undefined.
Also please note that I’ve created a constant newArr which is edited inside the map method and then returned as a log.

What am I missing?

its not just about logging, sometimes a function is only a small wheel in a much larger web

if you would log the result of the second function:

const shoutGreetings = arr => {
  const newArr = [];
  	arr.map(element => {
  	newArr.push(element.toUpperCase().concat('!'));
  })
  return console.log(newArr);
}

const greetings = ['hello', 'hi', 'heya', 'oi', 'hey', 'yo'];
console.log(shoutGreetings(greetings))

you will see undefined, that is what your function hands back.

i agree that in this case, logging is the intention, but its important to understand the difference

I see what you did there.

In both my snippets of code I’m only using console.log once.
In your example you’re logging out both inside the shoutGreetings function and on the global execution context.

Yes, logging out that way does return undefined.
But that’s not what I did.

If I’m missing something, please let me know.

but the instructions clearly state you need to return a new array:

Write a function shoutGreetings() that takes in an array of strings and returns a new array

returning the result also makes more sense once you have multiple functions which work together.

I’m sorry, I’m not following.

A new array is created as a constant, it’s called newArr.
A map() method is used which creates a new array.
This newArr is being returned in both snippets.

In the first snippet:
return newArr inside the functional context and logging out and calling the function in the global environment

In the second snippet:
return console.log(newArr) and calling the function in the global environment.

They print exactly the same on the console, yet only when I log out a function execution on the global environement, it is accepted as correct.

Also note that the assignment says:

You can use any technique you want to accomplish this task.

As a test, I created a new Array on the global environment and populated it with strings, tested it and got the same result. It prints out fine with both snippets, but the lower snippet is not accepted.

Also without altering both snippets, there is no return of undefined.

I think it might have to do with the back-end environment having hard-coded code which is required to be matching with what’s executed in the main.js file and not with what’s printed on the console.

its not. the second snippet returns the result of the .log() method.

returning and logging are not the same thing

1 Like

Hi,
I am also trying to crack this one. aflynt’s Code was a good attempt, and I have used mtf’s tip as well, so I placed the newArray call inside the function and appears to work.

const shoutGreetings = array => {
  let newArray = [];
  array.forEach(function(element) {
    newArray.push(element.toUpperCase() + "!");
}); return newArray;
                };

let greetings = ['hello', 'hi', 'heya', 'oi', 'hey', 'yo'];
  
  
console.log( shoutGreetings(greetings));


let example = ['just', 'to', 'prove', 'my', 'point'];

console.log(shoutGreetings(example));

//[ 'HELLO!', 'HI!', 'HEYA!', 'OI!', 'HEY!', 'YO!' ]
//[ 'JUST!', 'TO!', 'PROVE!', 'MY!', 'POINT!' ]

I didn’t have a problem with the logic/coding on this exercise, but I was confused by the syntax, which is why I’m not responding to anyone else’s post.

here is the solution

const shoutGreetings = arr => arr.map (word => word.toUpperCase() + '!')

I understand that because it is a single line block there does not have to be curly braces. What I don’t understand is why the return is undefined if brackets are included

const shoutGreetings = arr => 
{arr.map(word => 
{return word.toUpperCase() + '!'});
} 
//returns undefined

In the Concise Body Arrow Functions Exercise in the Functions Lesson, refactoring was introduced but instances of necessary refactoring were not mentioned. I guess I’m just looking for more elaboration on object method syntax.

2 Likes

in 2015 es6 (emcascript 2015) came out, an updated for the JS language.

before es6, we had es5, which was:

var shoutGreeting = function(name){
   return "hello " + name;
}

es6 introduced was is known as the arrow function:

const shoutGreeting = (name) => {
   return `hello ${name}`;
}

that is the full syntax, it also come with some shorthand’s, the first one being omitting the brackets if only a single parameter is present:

const shoutGreeting = name =>  { // no () around name
   return `hello ${name}`;
}

the other shorthand was that you can also omit the return keyword and curly brackets for single line functions:

const shoutGreeting = name => `hello ${name}`;

but this only works if you omit both return keyword and the curly brackets. Now the function will “automatically” return the result for you.

es6 also introduced const and let, and template literals, the ${} introduced to insert variables in a string (this only works when string is enclosed in back-ticks/grave accent)

3 Likes

why does this work

const shoutGreetings = arr => arr.map(word => word.toUpperCase() + ‘!’)

but this doesn’t

const shoutGreetings = arr => {arr.map(word => word.toUpperCase() + ‘!’)}

the only difference being the curly brackets

this:

const shoutGreetings = arr => arr.map(word => word.toUpperCase() + ‘!’)

is a shorthand for single line function, where by omitting the curly brackets, the result is automatically returned. Once you insert curly brackets, the return keyword is needed to return the data

1 Like

When I used below code it returns undefined and when I removed { } in const shoutGreetings = arr => { arr.map(word => word.toUpperCase());}; , it works just fine.

In the previous lectures, it was mentioned if it is a single line code, then we don’t need to use { } but I wasn’t aware it is mandatory not to use them. Could someone explain why { } shouldn’t be used?

const shoutGreetings = arr => {
  arr.map(word => word.toUpperCase());
};

const greetings = ['hello', 'hi', 'heya', 'oi', 'hey', 'yo'];

console.log(shoutGreetings(greetings));

its a shorthand, we could still do:

arr.map(word => { return word.toUpperCase() });

if we want.

Why not before arr.map though?