SyntaxError: Unexpected token [


#1

Maybe a fresh set of eyes can help figure out what's wrong here. Thanks

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);
}

function list() {
var contactsLength = contacts.length;
for (var i = 0; i < contactsLength; i++) {
printPerson(contacts[i]);
}
}

/*Create a search function
then call it passing "Jones"*/

function search(lastName){
for(var i = 0; i < contacts.length; i++){
if(lastName === contacts[i].lastName){
printPerson(contacts[i]);
};
};
};

function add(firstName,lastName,phoneNumber,email) {
var contacts[contacts.length] = {
this.firstName: "firstName";
this.lastName: "lastName";
this.phoneNumber: "phoneNumber";
this.email: "email";
contacts.push(this);
};
}
var Todd = new add ("todd","Smith","412-848-1094","will@me.com");
list();


#3
function add(firstName,lastName,phoneNumber,email) {
    var contacts[contacts.length] = {
    this.firstName: "firstName";
    this.lastName: "lastName";
    this.phoneNumber: "phoneNumber";
    this.email: "email";
    contacts.push(this);
};
}
var Todd = new add ("todd","Smith","412-848-1094","will@me.com");

There would appear to be some confusion around constructor and literal. The above is a morphing of both, and neither are successful, as it would prove out.

It comes down to choosing one way or the other, but not both. As the function starts out, we get the idea of a literal construction:

Oh, but everything grinds to a halt when we use var in this line...

var contacts[contacts.length] = {

Think about this for a second. Assuming we did not already have a contacts variable defined, and even while we do, how does one declare a variable and query its index length in one go? We don't.

To continue...

function add(firstName,lastName,phoneNumber,email) {
    contacts[contacts.length] = {
        firstName: firstName,
        lastName: lastName,
        phoneNumber: phoneNumber,
        email: email
    };
}

You will notice that we've tidied up the code. There is no this variable in literal syntax. The properties are directly contained in an anonymous object. The function parameters are not expressed as strings (in quotes) since they are variables, not strings. Lastly, properties in a literal object are separated by commas, not semi-colons.

Then we come to an equally valid approach using the Array.push() method.

function add(firstName,lastName,phoneNumber,email) {
    contacts.push({
        firstName: firstName,
        lastName: lastName,
        phoneNumber: phoneNumber,
        email: email
    });
}

Again, we use an anonymous object which can only now be referenced as the last element of the current array. In both of the above cases we have achieved our goal. Both approaches are correct.

This brings us to the constructor syntax in the original code. As this post is getting long, best save that for another.


#4

The one question that comes up is, do we want an exclusive constructor that only the add function has access to, or do we want a global constructor? For our purposes, let's stay away from global and give add exclusive control.

function add(f, l, p, e){
    function Contact(first, last, phone, email){
        this.firstName = first;
        this.lastName = last;
        this.phoneNumber = phone;
        this.email = email;
    }
    contacts.push(new Contact(f, l, p, e));    
}

add("Todd","Smith","412-848-1094","will@me.com");

This brings us to a new horizon. What if we want to have multiple contact lists driven by the same method store. Simple enough, we add a context variable, and give each object an instance reference that links it directly as the execution context.

function add(f, l, p, e){
    function Contact(first, last, phone, email){
        this.firstName = first;
        this.lastName = last;
        this.phoneNumber = phone;
        this.email = email;
    }
    this.push(new Contact(f, l, p, e));    
}
contacts.add = add;
contacts.add("Todd","Smith","412-848-1094","will@me.com");

Note there are actually two contexts in play here, which can get confusing. Read up on how to prevent this confusion from corrupting your code. I won't go more into now, for the sake of space and time.


#5

Thank you @mtf for explaining the mix up between syntax. Sometimes I feel like CA goes back and forth between it. Obviously, it confuses me and the outcome of my code. Clearly, there is more than one way to code a solution.

But I have more question related to this problem. why does the "list()" function have to appear in the solution? More specifically, shouldn't it be List(contacts)?

function add(firstName,lastName,phoneNumber,email) {
contacts.push({
firstName: firstName,
lastName: lastName,
phoneNumber: phoneNumber,
email: email
});
list();
}
add("todd","smith","tw@me.com","4124124122");


#6

I think for this exercise, list() takes no parameters. The author asks us to list after adding a new entry, just to confirm it is in the database. Be sure to write it AFTER the add() call expression, not inside the function.


#7

I don't know it it's right, but the code worked


#8

It will still work, that's true, just so long as the lesson checker doesn't squawk.


#9

Thanks again for your help. Its my first experience asking a question and probably I will try and be less shy to ask more. It definately adds value to the learning process and improves the coding experience. Have a good night?


#10

One more thing if thats ok? in the code below, in the list function, why do we have to create a variable "contactsLength"?

function list() {
	var contactsLength = contacts.length;
	for (var i = 0; i < contactsLength; i++) {
		printPerson(contacts[i]);

Couldn't have skipped the variable and just include the loop? For instance:

function list() {
    	for (var i = 0; i < contacts.length; i++) {
    		printPerson(contacts[i]);

#11

It won't be needed after this lesson, (I don't think) but the author must have just wanted to show us it can be done, and how to do it. The normal approach is to use the direct property in the for statement conditional.

There may be situations where the array is changing while the loop is running. Querying the property will always give the updated length, where a set variable will never change. But this is for another discussion. The main thing is once we practice it in this lesson, we get the point. Follow your second example going forward unless the lesson checker expects to see a variable (which I don't recall anywhere else).


#12

Thanks again for explaining it to me