object Object issue Javascript - javascript

I'm wokring with some assignements i got in school and I'm very new to coding. My goal is to present name FirstName & LastName of all all these variables in a span with an onclick. But the issue is that the loop seems to return [object Object] instead of the actual values of each new Person. It currently looks like this:
(I'm only to use pure Javascript without any help of Jquery or the use of Json with this code)
function Person(firstName, lastName, adress, phone) {
this.FirstName = firstName;
this.LastName = lastName;
this.Adress = adress;
this.Phone = phone;
}
var p1 = new Person("Anton", "Andersson","Nonstans", "1324565451");
var p2 = new Person("Felix", "Berge", "Krillan", "1234567889");
var p3 = new Person("Oscar", "Rells", "Essingen", "1234567888");
var p4 = new Person("Theodor", "Johansson", "Hemma", "1234567810");
var p5 = new Person("Jacob", "Lagstrom", "Ensam 78", "1234567892");
var Persons = [p1, p2, p3, p4, p5];
for (var i = 0; i < Persons.length; i++) {
var personList = document.getElementById("personLista")
personList.textContent += Persons [i] + ", ";
}

[object Object] is just the string representation of the entire object which is what you get since you are concatenating it with this string: ", ".
If you want to see the data within the object, you'll need to access a property of the object explicitly:
// JS convention is to use PascalCase for constructor functions
// as you are correctly doing here:
function Person(firstName, lastName, adress, phone) {
this.FirstName = firstName;
this.LastName = lastName;
this.Adress = adress;
this.Phone = phone;
}
var p1 = new Person("Anton", "Andersson","Nonstans", "1324565451");
var p2 = new Person("Felix", "Berge", "Krillan", "1234567889");
var p3 = new Person("Oscar", "Rells", "Essingen", "1234567888");
var p4 = new Person("Theodor", "Johansson", "Hemma", "1234567810");
var p5 = new Person("Jacob", "Lagstrom", "Ensam 78", "1234567892");
// But, JS convention is to use camelCase for all variables
var persons = [p1, p2, p3, p4, p5];
// Get this reference once, outside of the loop instead of each
// time you iterate over the array
var personList = document.getElementById("personLista");
for (var i = 0; i < persons.length; i++) {
// You need to access some aspect of the object (FirstName
// and LastName in this example) not the entire object itself:
personList.innerHTML += "<li>" + persons[i].FirstName + " " + persons[i].LastName + "</li>";
}
<ul id="personLista"></ul>
You may not have gotten to this in your assignments yet, but in ECMAScript 6 (introduced in 2015 and supported by most modern browsers today), arrays have a .forEach() method that makes it easier to iterate over their contents. Here's an example that first loops over the array, but then enumerates the properties of each object that is in the array:
function Person(firstName, lastName, adress, phone) {
this.FirstName = firstName;
this.LastName = lastName;
this.Adress = adress;
this.Phone = phone;
}
var p1 = new Person("Anton", "Andersson","Nonstans", "1324565451");
var p2 = new Person("Felix", "Berge", "Krillan", "1234567889");
var p3 = new Person("Oscar", "Rells", "Essingen", "1234567888");
var p4 = new Person("Theodor", "Johansson", "Hemma", "1234567810");
var p5 = new Person("Jacob", "Lagstrom", "Ensam 78", "1234567892");
var persons = [p1, p2, p3, p4, p5];
// Get this reference once, outside of the loop instead of each
// time you iterate over the array
var personList = document.getElementById("personLista");
// Loop over the array of people
persons.forEach(function(per){
// Beginning of a string of HTML that will be outputted at the end:
var personString = "<li>"
// Now enumerate all the properties of the person
for(var prop in per){
personString += per[prop] + ", ";
}
personString += "</li>"
personList.innerHTML += personString;
});
<ul id="personLista"></ul>

In Order to display values from object you need to access the properties from this object.
I have made an example on how to display values from the object.
function Person(firstName, lastName, adress, phone) {
this.FirstName = firstName;
this.LastName = lastName;
this.Adress = adress;
this.Phone = phone;
}
Person.prototype.toString = function() {
return this.FirstName + " " + this.LastName;
}
var p1 = new Person("Anton", "Andersson","Nonstans", "1324565451");
var p2 = new Person("Felix", "Berge", "Krillan", "1234567889");
var p3 = new Person("Oscar", "Rells", "Essingen", "1234567888");
var p4 = new Person("Theodor", "Johansson", "Hemma", "1234567810");
var p5 = new Person("Jacob", "Lagstrom", "Ensam 78", "1234567892");
var Persons = [p1, p2, p3, p4, p5];
for (var i = 0; i < Persons.length; i++) {
var personList = document.getElementById("personLista")
personList.textContent += Persons[i].toString() + ", ";
}
<span id="resultText1"></span>
<span id="resultText2"></span>
<input type="text" id="textRuta1"/> <input type="text" id="textRuta2"/>
<span id="arraySpan"></span>
<span id="personLista"></span>

You could overwrite toStirng() for Person object. The implementation could be:
function Person(firstName, lastName, adress, phone) {
this.FirstName = firstName;
this.LastName = lastName;
this.Adress = adress;
this.Phone = phone;
}
Person.prototype.toString = function personToString() {
var stringVal = 'FirstName: ' + this.FirstName + ' LastName: ' + this.LastName + ' Adress: ' + this.Adress + ' Phone: ' + this.Phone;
return stringVal;
}
var p1 = new Person("Anton", "Andersson","Nonstans", "1324565451");
var p2 = new Person("Felix", "Berge", "Krillan", "1234567889");
var p3 = new Person("Oscar", "Rells", "Essingen", "1234567888");
var p4 = new Person("Theodor", "Johansson", "Hemma", "1234567810");
var p5 = new Person("Jacob", "Lagstrom", "Ensam 78", "1234567892");
var Persons = [p1, p2, p3, p4, p5];
for (var i = 0; i < Persons.length; i++) {
var personList = document.getElementById("personLista")
personList.textContent += Persons[i].toString() + ", ";
}
You can modify function personToString() to format details as per your choice.

So many answers! Let me try one..
A) First, you can also use class nowadays, which is syntactic sugar for your Person.
B) just make an easy method you call when writing the full name.
it is more clear and easier.
C) the reason why you saw [Object object], is because you didn't load the property but the whole object.
Properties are firstName, lastName, address, phoneNumber
Objects are instances of the class Person
I have highlighted the problems in the code so you can learn more from it.
// A
class Person
{
constructor(firstName,
lastName,
address,
phoneNumber)
{
// javascript uses lower camelcase.
this.firstName = firstName;
this.lastName = lastName;
this.address = address;
this.phoneNumber = phoneNumber;
}
// B
getFullName()
{
return this.firstName + ' ' + this.lastName;
}
}
// create the list of people.
let persons = [
new Person("Anton", "Andersson","Nonstans", "1324565451"),
new Person("Felix", "Berge", "Krillan", "1234567889"),
new Person("Oscar", "Rells", "Essingen", "1234567888"),
new Person("Theodor", "Johansson", "Hemma", "1234567810"),
new Person("Jacob", "Lagstrom", "Ensam 78", "1234567892")
];
// iterate persons array using length.
for (let i=0; i<persons.length; i++)
{
// C
document.getElementById('personLista').innerHTML += persons[i].getFullName() + '<br />';
}
Hope it helps, good luck!

Related

Problem with calling a method using a prototype

Hi I have this code written and I want the output to be "bill jones is a snowboarder of beginner skill on the slopes.". I am getting "function () { return this.firstName + " " + this.lastName; } is a snowboarder of beginner skill on the slopes." I think the problem is the way I am calling the fullName method but I am stuck.
https://codepen.io/stefan927/pen/yLPJdQG?editors=1111
(function() {
const fullName = document.getElementById('fullName');
const type = document.getElementById('type');
const ability = document.getElementById('ability');
function Person(firstname, lastname, type, ability) {
this.firstName = firstname;
this.lastName = lastname;
this.type = type;
this.ability = ability;
}
Person.prototype.fullName = function() {
return this.firstName + " " + this.lastName;
}
var skier = new Person('Bill', 'Jones', 'snowboarder', 'beginner');
fullName.textContent = skier.fullName;
type.textContent = skier.type;
ability.textContent = skier.ability;
}())
Like Pointy pointed ( no pun intended ) out in his comment, you are not calling the fullName function which is invoked with a pair of (). So, in your code fullName.textContent = skier.fullName should be fullName.textContent = skier.fullName(). That should resolve your issue.
You have added fullName to the Persons prototype, and it's a function.
So you need to call/invoke this function.
fullName.textContent = skier.fullName(); //added () to fullName

Build a method that set properties to an object

I would like to build a method setName that set properties to an existing object.
const firstName = 'John'
const lastName = 'Rambo'
const existingObj = {};
existingObj.setName();
console.log(obj.firstName) // John
I am a bit lost between prototypes, class, and I am not sure where to start.
Shall I do this or is there a better solution ?
const setName = (obj) => {
obj.firstName = 'John'
obj.lastName = 'Rambo'
}
const newObj = {};
setName(newObj);
function Person(first, last) {
this.firstName = first;
this.lastName = last;
}
var john = new Person('John', 'Rambo');
console.log('Johns first name is ' + john.firstName);
You can the basics of JS objects and constructors here: https://www.w3schools.com/js/js_object_constructors.asp
To add a method to an existing object to set these values:
const firstName = 'John'
const lastName = 'Rambo'
const existingObj = {};
existingObj.setName = function(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
console.log('The name is ' + this.firstName + ' ' + this.lastName);
};
existingObj.setName('John', 'Rambo');

Why function that is property of the object isn't accessible once we add the same function to its prototype?

I have some basic understanding of why we use prototypical inheritance, while doing some stuff in my app I realized you can't really access a function once you add the function of the same name to its prototype. Why is that, Here is my code:
function person(firstname, lastname) {
this.firstname = firstname,
this.lastname = lastname,
this.greet = function() {
console.log('hey there', this.lastname + ' ' + this.firstname);
}
}
var jane = new person('jane', 'Doe');
jane.greet();
var john = new person('john', 'smith');
john.greet();
function person(firstname, lastname) {
this.firstname = firstname,
this.lastname = lastname
}
person.prototype.greet = function() {
console.log('hey there', this.lastname + ' ' + this.firstname);
}
var jane = new person('jane', 'Doe');
jane.greet();
var john = new person('john', 'smith');
john.greet();
Error thrown is:
"test.js:10
jane.greet();
^
TypeError: jane.greet is not a function"
Works for me. The only issue I could think of is you have re-declared (or tried to re-declare) the same method person within the same code block.
Edit for clarification: As pointed out by ASDFGerte, the second declaration of person overwrites the first version, which removes the internal method greet. You then try to use greet before the prototype expands person and re-adds the greet function.
function person(firstname, lastname) {
this.firstname = firstname,
this.lastname = lastname,
this.greet = function() {
console.log('hey there', this.lastname + ' ' + this.firstname);
}
}
var jane = new person('jane', 'Doe');
jane.greet();
var john = new person('john', 'smith');
john.greet();
function person2(firstname, lastname) {
this.firstname = firstname,
this.lastname = lastname
}
person2.prototype.greet = function() {
console.log('(2) hey there', this.lastname + ' ' + this.firstname);
}
var jane2 = new person2('jane2', 'Doe');
jane2.greet();
var john2 = new person2('john2', 'smith');
john2.greet();

adding to an array from a previous function

so I would like to access an an array i created in a previous function. and then in id1,id2,id3, i would Like to create a new property and give that property a value. I thought I have an idea of what I should do but what Im doing is not working. I get the error IdArray is undefined.
HTML:
<p id="show_me"></p>
<button onclick="ObjectArray()">click me</button>
<p id="added"></p>
<button onclick="Added()">Add</button>
javascript previous function:
var ObjectArray = function() {
// object literal
var id1 = {
firstName: "John",
lastName: "Doe",
id: "12345"
};
// keyword new
var id2 = new Object;
id2.firstName = "Adam";
id2.lastName = "Bakely";
id2.id = "abcdef";
// object constructor
function employee(first, last, id) {
this.firstName = first;
this.lastName = last;
this.id = id;
}
var id3 = new employee("Dallas", "Star", "abc123");
//create an array
var IdArray = [id1, id2, id3];
}
javascript new function:
function Added(IdArray, sex){
IdArray.push({sex : sex})
IdArray[0].sex = "male";
document.getElementById("added").innerHTML = IdArray[0];
}
im lost, so how do I access the array from the previous function and add to it?
You do not have access to variables in other functions, you can however access variable declared above your functions. Your real problem is a failure to understand Constructors, which will greatly benefit you in the future. Check this out:
function Employee(id, firstName, lastName, middleName){
this.id = id; this.firstName = firstName; this.lastName = lastName;
this.middleName = middleName;
this.notes = [];
this.getFullName = function(){
var mn = this.middleName ? ' '+this.middleName : '';
return this.firstName+mn+' '+this.lastName;
}
this.createNote = function(note){
this.notes.push(note);
return this;
}
this.getNotesString = function(delimiter){
return this.notes.join(delimiter);
}
}
var employee1 = new Employee('abc123', 'Joe', 'Schmoe');
employee1.createNote('Note You Want to Store.');
employee1.createNote('Just Another Test Note.');
var employee2 = new Employee('def456', employee1.firstName, 'Smith', 'Walter'); // notice how you access the other instance firstName
console.log(employee1.getFullName());
console.log(employee1.getNotesString('|'));
console.log(employee2.getFullName());
console.log(employee2.createNote('Note 1').createNote('Note 2').createNote('Note 3').getNotesString('|')); // by returning `this` you can access other methods in the same Constructor
You need to either save the IdArray or to return it:
var IdArray;
var ObjectArray = function() {
// object literal
var id1 = {
firstName: "John",
lastName: "Doe",
id: "12345"
};
// keyword new
var id2 = new Object;
id2.firstName = "Adam";
id2.lastName = "Bakely";
id2.id = "abcdef";
// object constructor
function employee(first, last, id) {
this.firstName = first;
this.lastName = last;
this.id = id;
}
var id3 = new employee("Dallas", "Star", "abc123");
//create an array
IdArray = [id1, id2, id3]; //removed the var keyword, so I am using the global variable
}
and then use it.
notice I removed the var keyword so I am using the global IdArray.
The variable IdArray was created inside the function, so it expires when the function ends. If you add the line
var IdArray;
before your first function that will make it global instead. Then reference to IdArray inside either function will refer to the same variable.
I added the IdArray as a property of the window object to give it global scope:
var ObjectArray = function() {
// object literal
var id1 = {
firstName: "John",
lastName: "Doe",
id: "12345"
};
// keyword new
var id2 = new Object;
id2.firstName = "Adam";
id2.lastName = "Bakely";
id2.id = "abcdef";
// object constructor
function employee(first, last, id) {
this.firstName = first;
this.lastName = last;
this.id = id;
}
var id3 = new employee("Dallas", "Star", "abc123");
//create an array
window.IdArray = [id1, id2, id3];
}

javascript constructors involving unknown amounts of arguments...

I was messing with some js on codecadamy and got a bit sidetracked trying to make something work.
In essence I was creating a few objects that are loaded into a controller object and set as properties of it with two functions that print the properties and compare a string to the name property of each object in the controller.
I noticed I can do it if I make the objects in the prototype style and specify a normal function to handle setting the properties like so:
var friends = {};
friends.setUp = function() {
this.friends = [];
for(var i in arguments) {
arguments[i].setUp();
this.friends.push(arguments[i]);
}
};
friends.list = function() {
for(var i in this.friends) {
console.log(this.friends[i]);
}
};
friends.search = function(name) {
for(var i in this.friends) {
if(this.friends[i].firstName === name) {
return this.friends[i];
}
}
};
var bill = {};
bill.setUp = function() {
this.firstName = "Bill";
this.lastName = "Gates";
this.number = "(206) 555-5555";
this.address = ['One Microsoft Way','Redmond','WA','98052'];
};
var steve = {};
steve.setUp = function() {
this.firstName = "Steve";
this.lastName = "Jobs";
this.number = "(206) 555-5555";
this.address = ['1 Infinite Loop','Cupertino','CA','95014'];
};
var mike = {};
mike.setUp = function() {
this.firstname = "Mike";
this.lastname = "Ryd";
this.number = "(800) 555-5555";
this.address = ['redacted'];
};
friends.setUp(bill, steve, mike);
friends.list();
var result = friends.search("Steve");
console.log(result);
However if I do it with constructors It does not work, example:
function bill() {
this.firstName = "Bill";
this.lastName = "Gates";
this.number = "(206) 555-5555";
this.address = ['One Microsoft Way','Redmond','WA','98052'];
};
function steve() {
this.firstName = "Steve";
this.lastName = "Jobs";
this.number = "(206) 555-5555";
this.address = ['1 Infinite Loop','Cupertino','CA','95014'];
};
function mike() {
this.firstname = "Mike";
this.lastname = "Ryd";
this.number = "(800) 555-5555";
this.address = ['redacted'];
};
function friends() {
this.friends = [];
for(var i in arguments) {
this.friends.push(arguments[i]);
}
};
friends.list = function() {
for(var i in this.friends) {
console.log(this.friends[i]);
}
};
friends.search = function(name) {
for(var i in this.friends) {
if(this.friends[i].firstName === name) {
return this.friends[i];
}
}
};
var bill = new bill();
var steve = new steve();
var mike = new mike();
var friends = new friends(bill, steve, mike);
friends.list();
var result = friends.search("Steve");
console.log(result);
I was wondering if this is a limitation of using constructors or am I messing up the syntax somewhere? Thank you!
This doesn't appear to have anything to do with constructors with an unknown number of arguments, but rather you are not assigning methods on your objects appropriately. They need to be put on the prototype so that they will be inherited by all objects that are created by this particular constructor. So in your code, these:
friends.list = function() {...}
friends.search = function() {...}
needs to be changed to:
friends.prototype.list = function() {...}
friends.prototype.search = function() {...}
Like this:
friends.prototype.list = function() {
for(var i = 0; i < this.friends.length; i++) {
console.log(this.friends[i]);
}
};
friends.prototype.search = function(name) {
for(var i = 0; i < this.friends.length; i++) {
if(this.friends[i].firstName === name) {
return this.friends[i];
}
}
};
Then, this code should work fine:
var bill = new bill();
var steve = new steve();
var mike = new mike();
var friends = new friends(bill, steve, mike);
friends.list();
var result = friends.search("Steve");
console.log(result);
And, then the code works as you would expect here: http://jsfiddle.net/jfriend00/ba4me8ua/
FYI, you'll noticed that I changed the way you iterate through the arguments object items to be more array-like and avoid any chance of getting any non-numeric properties in the iteration.

Categories