How do I capitalize the first letter of each contact's first name?
String.prototype.capitalize = function (string) { return string.charAt(0).toUpperCase() + string.slice(1);}
var contactList = {};
contactList.bobSmith = {
firstName: "bob",
lastName: "smith",
location: "new york"
};
contactList.johnDoe = {
firstName: "john",
lastName: "doe",
location: "san francisco"
};
var contact2 = contactList["johnDoe"].firstName;
contact1.capitalize();
contact2.capitalize();
console.log(contact1 + " " + contact2);
I get an error message that says "Uncaught TypeError: Cannot read property 'charAt' of undefined".
function () { return this.charAt(0).toUpperCase() + this.slice(1);}
Your String.prototype.capitalize function requires an argument string which you're not passing to it when called. I'd recommend avoiding adding methods to the String.prototype and just use a stand-alone function instead...
function capitalise(str) {
return str.slice(0,1).toUpperCase() + str.slice(1);
}
contact2 = capitalise(contact2);
//=> "John"
...or if you're looking to capitalise the value in the contactList object, then just...
contactList.johnDoe.firstName = capitalise(contact2);
Hope that helped. :)
I wouldn't make it a habit of popping methods into prototype. It's frowned upon because future versions of JavaScript could come out and put a method with the same name in the prototype and you would be screwed.
I didn't write it this way but you could put the capitalize function on to the contactList object and you would basically achieve the same thing your trying to do with the prototype.
var contactList = {};
contactList.names =[
{
firstName: "bob",
lastName: "smith",
location: "new york"
},
{
firstName: "john",
lastName: "doe",
location: "san francisco"
}];
function capitalizeName(name) {
var strCap = name[0].toUpperCase();
var tailTxt = name.substr(1, name.length);
fullTxt = strCap + tailTxt;
return fullTxt;
)
$.each( contactList.names, function(i){
capitalizeName(contactList.names[i].firstName);
});
Related
I have an array of objects that needs sorting by last name, however the object only has firstname and fullname parameters, so for last name I have to use fullname.replace((firstname + " "), ""). Example array below.
const names = [
{
firstname: "John",
fullname: "John Doe"
},
{
firstname: "Amber",
fullname: "Amber Smith"
},
{
firstname: "Michael",
fullname: "Michael Smith"
},
{
firstname: "Jessica",
fullname: "Jessica Kelly Charles"
}
]
While I can use the "replace" every time inside a sort compare function, I'd much rather have something like this:
names.sort(function(a, b) {
const lastname = fullname.replace((firstname+ " "), "");
if (a.lastname < b.lastname) {
return -1;
} else if (a.lastname > b.lastname) {
return 1;
}
return 0;
});
Obviously lastname comes up as undefined.
This has been rather hard to google for, and I think I'm missing some JavaScript basics here, but would greatly apprecite your help in helping me learn to write better code.
Your best bet is to modify the source of the array so it stores lastname upon collection.
If you can't do that:
Unless you do a prep pass through your array adding a lastname property, you'll have to compute it each and every time your sort callback is called, for both a and b.
names.sort((a, b) => {
const alast = a.fullname.replace(a.firstname + " "), "");
const blast = b.fullname.replace(b.firstname + " "), "");
return alast.localeCompare(blast);
});
(Note I used localeCompare, which is always a better choice for names and other natural language strings than < and >. For instance, ask the French whether รง should really come after z as it does with < and >. ;-) )
That will recompute the lastname for the same object repeatedly, though, since the same object may be passed to sort (as either a or b) repeatedly. If you think that may be a problem, you could do that prep pass I mentioned:
// Build a map of entry to last names
const lastnames = new Map(names.map(entry => {
const lastname = entry.fullname.replace(entry.firstname + " ", "");
return [entry, lastname];
}));
// sort
names.sort((a, b) => {
return lastnames.get(a).localeCompare(lastnames.get(b));
});
You are just declaring a new variable trying to access it via object's property. You should map your data in the first place like:
const names = [
{
firstname: "John",
fullname: "John Doe"
},
{
firstname: "Amber",
fullname: "Amber Smith"
},
{
firstname: "Michael",
fullname: "Michael Smith"
},
{
firstname: "Jessica",
fullname: "Jessica Kelly Charles"
}
].map(person => ({
...person,
lastName: person.fullName.replace(person.firstName + ' ', '')
}));
After mapping your data like that, you can use .lastName in the place you need.
names.sort(function(a, b) {
if (a.lastName < b.lastName) {
return -1;
} else if (a.lastName > b.lastName) {
return 1;
}
return 0;
});
Codecademy code
I have successfully completed a JavaScript exercise in Codecademy entitled 'contact list' with the code:
var friends = {};
friends.bill = {
firstName: "Bill",
lastName: "Gates",
number: "(206) 555-5555",
address: ['One Microsoft Way','Redmond','WA','98052']
};
friends.steve = {
firstName: "Steve",
lastName: "Jobs",
number: "(408) 555-5555",
address: ['1 Infinite Loop','Cupertino','CA','95014']
};
var list = function(obj) {
for(var prop in obj) {
console.log(prop);
}
};
var search = function(name) {
for(var prop in friends) {
if(friends[prop].firstName === name) {
console.log(friends[prop]);
return friends[prop];
}
}
};
list(friends);
search("Steve");
This outputs:
bill
steve
{ firstName: 'Steve',
lastName: 'Jobs',
number: '(408) 555-5555',
address: [ '1 Infinite Loop', 'Cupertino', 'CA', '95014' ] }
{"firstName":"Steve",
"lastName":"Jobs",
"number":"(408) 555-5555",
"address":["1 >Infinite Loop","Cupertino","CA","95014"]}
I then changed the list and search functions slightly so that it outputs in chrome correctly:
var list = function(obj) {
for(var prop in obj) {
document.write(prop + "<br>");
}
};
var search = function(name) {
for(var prop in friends) {
if(friends[prop].firstName === name) {
document.write(friends[prop]);
return friends[prop];
}
}
};
This returned the output:
bill
steve
[object Object]
Question:
Where does this [object Object] output come from?
How can I return the correct output from search function?
Note:
The list function is working fine, but there is a problem with the search function. The friends[prop].firstName in the for loop is not returning anything.
Thanks in advance for the help
The string [object Object] is the default string representation of a Javascript object. You will get that when you try to write out any object. In your example, console.log does a bit of magic that converts for you automatically:
document.write({});
document.write({ a: 'b' });
What you can do to output a more helpful version of a JS Object is using JSON. Thankfully, JS provides a nice little function for converting objects into strings:
document.write(JSON.stringify({}));
document.write(JSON.stringify({ a: 'b' }));
document.write(friends[prop]) shows oupput as [object Object], access property by property name.
var search = function (name) {
for (var prop in friends) {
if (friends[prop].firstName === name) {
//document.write(friends[prop]);
var oProp = friends[prop]
document.write(oProp.address + "<br/>" + oProp.firstName);
//return friends[prop] - as an object
//return oProp.address - as a single property
//return JSON.stringify(oProp) - as a JSON string
return friends[prop];
}
}
};
I have 2 objects which is bob and mary and i want to call their firstName and lastName values in a function with using an array but this code doesn't seem to work
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];
var printPerson = function(person) {
console.log(this.firstName + " " + this.lastName);
}
printPerson(contacts[0]);
printPerson(contacts[1]);
What am i missing ?
In your function this refers to the window object.
Use the object that is passed to the function as parameter.
Use person.firstName and person.lastName to get the names from the respective object.
var printPerson = function(person) {
console.log(person.firstName + " " + person.lastName);
// ^^^^^^ ^^^^^^
}
You need to access firstName and lastName attributes from person parameter. So, your code must be:
var printPerson = function(person){
console.log(**person**.firstName + " " + **person**.lastName);
}
The search function in the following code is not working and I believe it has something to do with the For...In loop but I am new to JS and unsure why:
var friends = {
bill: {
firstName: "bill",
lastName: "smith",
number: 1,
address: ["1"]
},
steve: {
firstName: "steve",
lastName: "smith",
number: 2,
address: ["2"]
}
};
var list = function(list) {
for(var item in list) {
console.log(item);
}
};
var search = function(name) {
for(var friend in friends) {
if(friend.firstName === name) {
console.log(friend);
return friend;
}
}
};
search("steve");
The for in loop iterates over keys, not values.
friend is a string holding the name of each property.
To get the value, use friends[friend].
Great documentation of the for..in loop can be found on mdn. Where variable is assigned through each iteration to "a different property name".
You also may not need to loop through each friend. What if you changed your search function to use hasOwnProperty on the object:
var search = function(name) {
if(friends.hasOwnProperty(name)){
return friends[name];
}
};
This would check that you have a property of name in the object friends and return it. Here's a quick EXAMPLE.
I want to create some custom javascript objects some of which have properties which are other objects. I'm not sure what the syntax would be to do this. My pseudo code is below with the idea that I have a person object and an order object. The order object has a property that I want to be of the person object type. Is this possible in javascript and if so, can someone give me a basic example? Thanks.
var person {
name: "John",
gender: "M",
age: 3
}
var order {
customer: person, /*the property name is customer but of type person - is this possible?*/
total: 100
}
Consider constructors:
function Person( name, gender, age ) {
this.name = name;
this.gender = gender;
this.age = age;
}
function Order( customer, total ) {
this.customer = customer;
this.total = total;
}
Usage:
var person1 = new Person( 'John', 'M', 3 );
var order1 = new Order( person1, 100 );
The constructors act as classes. You invoke them via new to create new instances (persons and orders).
You were almost correct; all you need is to include some '='
var person = {
name: "John",
gender: "M",
age: 3
}
var order = {
customer: person, /*the property name is customer but of type person - is this possible?*/
total: 100
}
You could do this:
var person = {
name: "John",
gender: "M",
age: 3
};
var order = {
customer: person,
total: 100
};
This also passes in JSLint. You were missing '=' signs.
You code is nearly fine (missing the = to assign the anonymous object to the variable):
var person = {
name: "John",
gender: "M",
age: 3
};
var order = {
customer: person, /*the property name is customer but of type person - is this possible?*/
total: 100
};
http://jsfiddle.net/D7u3x/
Sure, thats pretty much it. Your syntax is a little off, but only slightly.
Here is your example: jsfiddle