Why does this function print out 'undefined'? - javascript

The list function below is supposed to list the names of the people in my contacts array.
var bob = {
firstName: "Bob",
lastName: "Jones",
phoneNumber: "(650) 777-7777",
email: "bob.jones#example.com"
};
var mary = {
firstName: "Mary",
lastName: "Johnson",
phoneNumber: "(650) 888-8888",
email: "mary.johnson#example.com"
};
var contacts = [bob, mary];
function printPerson(person) {
console.log(person.firstName + " " + person.lastName);
}
var list = function() {
var contactsLength = contacts.length;
for (var i = 0; i < contactsLength; i++) {
console.log(printPerson(contacts[i]));
}
};
list;
However, instead of just printing out Bob Jones and Mary Johnson, I get:
Bob Jones
undefined
Mary Johnson
undefined
Can someone explain why this is?

Your printPerson method writes to the console, but does not return any value, so in your for-loop where you have:
for (var i = 0; i < contactsLength; i++) {
console.log(printPerson(contacts[i]));
}
It's also trying to write the return value of printPerson to the console, which is undefined.
To fix this, either drop the console.log from the for-loop or return a value from printPerson rather than writing to the console there.

Try this:
function printPerson(person) {
return person.firstName + " " + person.lastName;
}

Your printPerson function writes to the console. It does not return a value explicitly. When a function without an explicit return value runs, it returns the undefined value. The console always tries to display the return value of a function after it runs, if an explicit value is not set, it returns the value undefined.

Related

if else statement javascript returns false statement

Could someone help me with this code, I'm trying to write a function that takes in a name from an object and returns a name tag :
"Hi! I'm [name], and I'm from [country]."
I've tried this code
const GUEST_LIST = {
Randy: "Germany",
Karla: "France",
Wendy: "Japan",
Norman: "England",
Sam: "Argentina"
}
function greeting(name) {
var x = Object.keys(GUEST_LIST);
const array = Object.keys(GUEST_LIST)
.map(function(key) {
return GUEST_LIST[key];
});
var txt ="";
for (let i in x)
{
if (name === x[i])
{
txt = "Hi I'm "+x[i] +", and I'm from " +array[i];
}
else
{
txt = "Hi! I'm a guest";
}
}
return txt;
}
console.log(greeting("Randy"))
but it always returns "Hi! I'm a guest" except when I type Sam,
Your issue is that your for loop will continue to loop over the other names in your x array even after you have found a name from your array that matches the name you passed into your function. That means on further iterations of your for loop, your else block of your code will run and overwrite the value of txt previously set. That's why "Sam" works, as that's the last name in your x array, and so txt doesn't get overwritten by further iterations of your for loop.
Another thing to note about your code, a for...in loop shouldn't be used to iterate over an array. It can lead to unwanted values being accessed, as it doesn't just loop over the indices of your array, but rather other properties.
With that being said, you're over-engineering your code. Currently, your object stores key-value pairs. The key is the name and the value is the country. For each key in your object, you can access it using bracket-notation:
console.log(GUEST_LIST["Randy"]); // Germany
With that idea in mind, your name variable can be used as the key for your object, which can then be used to obtain the country. If the GUEST_LIST object doesn't contain your key (ie: the value returned by trying to access the key from your object is falsy), then you can return your default "Hi! I'm a guest" text:
const GUEST_LIST = {
Randy: "Germany",
Karla: "France",
Wendy: "Japan",
Norman: "England",
Sam: "Argentina"
};
function greeting(name) {
const country = GUEST_LIST[name];
if(country)
return "Hi I'm "+name +", and I'm from " +country;
else
return "Hi! I'm a guest";
}
console.log(greeting("Randy"));
Since there are no specifications, why there should a for loop, why not make it a bit more simple?
const GUEST_LIST = {
Randy: 'Germany',
Karla: 'France',
Wendy: 'Japan',
Norman: 'England',
Sam: 'Argentina'
}
function greeting (name) {
if (GUEST_LIST[name]) {
return "Hi I'm " + name + ", and I'm from " + GUEST_LIST[name]
} else {
return "Hi! I'm a guest"
}
}
console.log(greeting('Randy'))
console.log(greeting('The guy from the bus stop'))
To appreciate what I mean here is the working version of your code.
for (let i in x)
{
if (name === x[i])
{
txt = "Hi I'm "+x[i] +", and I'm from " +array[i];
break; // <---- stop the loop here when you find a match
}
else
{
txt = "Hi! I'm a guest";
}
}
return txt;
}
Simple to read and short:
const GUEST_LIST = {
Randy: "Germany",
Karla: "France",
Wendy: "Japan",
Norman: "England",
Sam: "Argentina"
}
function greeting(name){
return (GUEST_LIST[name]) ?
`Hi, I'm ${name} and I'm from ${GUEST_LIST[name]}` :
`Hi! I'm a guest`
}
console.log(greeting("Randy"))

Update 'nested' javascript object dynamically

I'm trying to create an object that is updated dynamically.
Here's the setup of the type of object I'd like to create (note: I may add other things, such as address, country, etc to the keys):
var contacts = {"Bruce Wayne":{"phone number":'123-456-7890', "email":"bwayne#night.com"}, "Alfred":{"phone number" :'987-654-3210', "email": "alfred#yourang.com"}, "Clark Kent":{"phone number":'951-753-8520', "email":"nothing#krypton.com"}}
So for each name (Bruce Wayne, Alfred, ...) I have some keys assigned to them.
I'm using npm faker to generate some fake data to try and populate an array like the above, with the outline
I'm able to get a loop going, but it always returns the last iteration's data. I understand it's because I'm doing contact = .... Since this is an object, I can't use push, AFAIK.
function getContact(numContacts){
contacts = {}
for (var i = 0; i < numContacts; i++){
console.log(i);
var name = faker.name.firstName() + " " + faker.name.lastName();
var phoneNum = faker.phone.phoneNumber();
var email = faker.internet.email();
contacts = {name :{ "phone number": phoneNum, "email": email}}
// contacts.name = {"phone number": phoneNum, "email":email}; // this also returns just the last instance.
};
return contacts;
};
var contacts = getContact(10); // This should create ten people, each with a phone number and email.
The loop almost successfully creates a single name. This returns:
name, 761.704.3328 x4287, Leopold81#hotmail.com
But in that iteration, name variable is actually Joe Schmoe, not literally name...
What am I overlooking to make sure that the contacts object gets populated with 10 people, with the resolved name, not just the last in the iteration?
Observations
You're trying to use name variable as key, however, what you're doing is adding a key literally called name.
What you have to do, is to create the key programmatically as follow: contacts[name] and assign the object with phoneNumber and Email.
This code is an example to simulate your scenario.
var faker = {
name: {
firstName: function() {
return "Clark";
},
lastName: function() {
return "Kent";
}
},
phone: {
phoneNumber: function() {
return '951-753-8520';
}
},
internet: {
"email": function() {
return "nothing#krypton.com";
}
}
};
function getContact(numContacts) {
var contacts = {}
for (var i = 0; i < numContacts; i++) {
var name = faker.name.firstName() + " " + faker.name.lastName();
var phoneNum = faker.phone.phoneNumber();
var email = faker.internet.email();
contacts[name + '_' + i] = {
"phone number": phoneNum,
"email": email
}
}
return contacts;
}
var contacts = getContact(10);
console.log(contacts);
The names are the keys in your object. You can use it like an array index to populate contacts. This should work:
contacts[name] = {"phone number": phoneNum, "email": email}

I don't understand this function. [Codecademy Contact List excercise]

So the "for var x in friends" loop is going to search each key inside friends, which would be bill and steve, and then with "friends[x].firstName === name" we are checking if the first name is equal to "name", but how does the program know if "name" is Steve or Bill? I'm missing something here.
var friends = {
bill: {
firstName: "Bill",
lastName: "Gates",
number: " ",
address: [' ', ' ', ' ',' ']
},
steve: {
firstName: "Steve",
lastName: "Jobs",
number: " ",
address: [' ', ' ', ' ',' ']
}
};
var list = function(friends) {
for (var x in friends) {
console.log(x);
}
};
var search = function(name) {
for (var x in friends) {
if(friends[x].firstName === name) {
console.log(friends[x]);
return friends[x];
}
}
};
for (var x in friends)
This iteates over all keys in friends, resulting in two loop iterations with
x = "bill"
x = "steve"
Then with friends[x] in the loop you access friends.bill and freinds.steve.
The name variable is given as a parameter to search(name). This effectivly searches all entries in the dict friends for firstName == name.
here we have defined search as a function search which accepts an argument name .
var search = function(name)
and we use the function like
search('Bill')
So the function knows which name we are looking for, which is Bill . It will iterate through each item and compare each firstName with Bill. It returns the corresponding friends[x] , when it finds a match .
The advantage of function with parameter is that, with the same function we can search for any name . ex : search('Steve') , search('Bill') .
if you don't understand functions with parameters, revisit the codeacademy section understanding parameters - js

CodeAcademy javascript questing

I am working on codeAcademy's javascript section and I am so stuck on one of the exercises.
Here is my code:
var friends = {
bill:{
firstName:"Bill",
lastName: "Gates",
number:"(206)555-5555",
address:['One Microsoft Way', 'Redmond','wa','12345']
}
};
var friends = {
steve:{
firstName:"Steve",
lastName: "Jobs",
number:"(555)555-5555",
address:['One Apple Way', 'San Diego','ca','12345']
}
};
var list = function()
{
for (var something in friends)
console.log(something);
}
var search = function(name)
{
for (var contact in friends)
{
if (contact == name)
{
for (var contact_info in friends.name)
{
console.log(contact_info);
}
}
}
}
I am pretty confused about the for/in loop. I have been working on this exercise for a while and was wondering if someone could help me understand. Mainly the search function. Its suppose to be able to see if the given name is in the the object and print the contact info associated. I am completely lost. I even tried restarting the whole section and still got stuck.
In Javascript, the for-in loop will go through each of an object properties.
Your friends object is first created having only one property, which is also an object, describing Bill Gates. Then it it overwritten by another object that also has only one property, but now describing God Steve Jobs.
Finally, in the search function, you are going through each property of friends and comparing them to a string. Inside a for-in loop, name is a variable that contains the name of the property used in the current iteration of the loop. So you'll get a match if you use the names of the variables (i.e.: steve). If you wish to match the names stored in the object, you have to use a parameter that is not called name in the declaration of the search function, and make the check like this:
if (contact.firstName == _name || contact.lastName == _name ||
(contact.firstName + " " + contact.lastName) == _name)
Also notice that after you create your friends variable with Bill, you then recreate it with Steve. So you end up with only one "contact" in that variable. You could change your object declarations like this:
var friends = {}; // This creates an empty object
friends.bill = {
firstName: "Bill",
lastName: "Gates" // And so on...
};
friends.steve = {
firstName: "Steve" // You get the drill
};
And then your friends object would have both pirates of the Sillicon Valley now.
First of all you have wrong friends var definition, you override Bill with Steve.
It suppose to be similar to this
var friends = {
bill:{
firstName:"Bill",
lastName: "Gates",
number:"(206)555-5555",
address:['One Microsoft Way', 'Redmond','wa','12345']
},
steve:{
firstName:"Steve",
lastName: "Jobs",
number:"(555)555-5555",
address:['One Apple Way', 'San Diego','ca','12345']
}
};
Now the answer to your question.
function search(name)
{
// Length of friends object received using Object.keys
for (var p = 0; p < Object.keys(friends).length ;p++)
{
if(friends[name] != undefined){
// Add to console and stop function execution if match found.
console.log(friends[name].firstName);
return;
}
}
}
Some explanation.
If "friends[name]" is undefined it means that you don't have object with specified name.
If it returns some Object you just get the value of the "firstName" or any other property in the object.
A for in loop in Javascript will loop through each property of an object. Unfortunately, your object will only have 1 property steve because you overwrite the entire object with your second var friends = ... statement. When looping through an object, your name variable will be the string index of your friend in the friends object. Once you find a match for the name, you can use the contact information by using friends[name]. If you are looking for a friend with the same first name as your search, you may want to look at the specific first name
Just as a side note, because Javascript is a loosely typed language, there is no need to loop through the entire friends object to see if you have a friend with that name. Here is a code sample:
var friends = {
bill: {
firstName: 'Bill',
lastName: 'Gates'
},
steve: {
firstName: 'Steve',
lastName: 'Jobs'
},
steve2: {
firstName: 'Steve',
lastName: 'Doe'
}
},
search1 = function(name) {
if(friends[name] !== undefined) { //Is there a friend with this index
//Yay, we have a friend with this index!
}
else {
//Sorry, we don't have a friend with this index
}
},
search2 = function(name) {
name = name.toLowerCase(); //Case insensitive
for(var friend in friends) {
if(friends[friend].firstName.toLowerCase() == name) { //Does this person have the same first name
//This friend has the same first name
}
}
};
search1('steve'); //Will only give us Steve Jobs
search2('steve'); //Will give us Steve Jobs and Steve Doe

Why does this function print "undefined undefined" as a contact name, added with “new Object”?

I’m working on the JavaScript course at Codecademy. In this exercise, we’re supposed to create the function add which is supposed to add a person to the contacts array, then use prompts to get information from a user, after which we call the function list to print all the people in the contacts array to the console.
When I run the code below, it lists the two existing persons in the contacts array, but then prints "undefined undefined" for the person that I’ve tried to add with the prompts. When I print the length of contacts, however, it says 3, so a person has been added.
Any help would be greatly appreciated.
var bob = {
firstName: "Bob",
lastName: "Jones",
phoneNumber: "(650) 777 - 7777",
email: "bob.jones#example.com"
};
var mary = {
firstName: "Mary",
lastName: "Johnson",
phoneNumber: "(650) 888 - 8888",
email: "mary.johnson#example.com"
};
var contacts = new Array(bob, mary);
function printPerson(person) {
console.log(person.firstName + " " + person.lastName);
}
function list() {
var length = contacts.length;
var i;
for (i = 0; i < length; i++) {
printPerson(contacts[i]);
}
}
/*Create a search function
then call it passing "Jones"*/
var search = function(lastName) {
var number = contacts.length;
for (i = 0; i < number; i++) {
if (contacts[i].lastName === lastName) {
printPerson(contacts[i]);
}
}
};
var add = function(firstName, lastName, email, telephone) {
contacts[contacts.length] = new Object(firstName, lastName, email, telephone);
};
var firstName = prompt("What is your first name");
var lastName = prompt("What is your last name");
var email = prompt("What is your email");
var telephone = prompt("What is your phone number");
add(firstName, lastName, email, telephone);
list();
To create a new object with properties, you have to give it both property name and property value for each property. You were just passing a list of values to the new Object() constructor which does not make the type of object you wanted.
There are several ways to create a new object with properties, but in this case, it's probably easiest to just use the literal object declaration format {name1: val1, name2: val2}. To do that, change this code:
var add = function(firstName, lastName, email, telephone){
contacts[contacts.length] = new Object(firstName, lastName, email, telephone);
};
to this:
var add = function(firstName, lastName, email, telephone){
contacts[contacts.length] = {firstName: firstName, lastName: lastName, email: email, phoneNumber: telephone};
};
It works here: http://jsfiddle.net/jfriend00/Ea7B5/

Categories