1

I have a piece of script here that creates an object constructor, then buildList() takes data from a spreadsheet and spits out an array containing department names. what I'm trying to do in buildObjects() is use that array to create an object for each department and then fill it with various values pertaining to the department. Obviously I'm having trouble with the line var ADCnames[i] = new ADC(ADCnames[i]);

function ADC(name) {
  this.name = name;
}

function buildObjects () {
  var ADCnames = buildList('ADC', 1);
  var ADCarray = [];
  for (var i in ADCnames) {
    var ADCnames[i] = new ADC(ADCnames[i][0]);
    ADCarray.push(<<the variable I just created>>);
  }
  return ADCarray;
}

I'm new to using objects so there may be a simpler way that I'm missing. Any help is appreciated.

1
  • 2
    for what it is worth, it is sometimes worth not using 'name' as an atrribute as it can be a reserved word. Not always a problem, but can cause difficult to debug problems down the wire. quackit.com/javascript/javascript_reserved_words.cfm Commented Feb 18, 2013 at 16:18

2 Answers 2

2

All you have to do is rename the variable.

Try

function buildObjects () {
  var ADCnames = buildList('ADC', 1);
  var ADCarray = [];
  for (var i in ADCnames) {
    var tempADC = new ADC(ADCnames[i][0]);
    //do whatever else you need to do to this object.
    ADCarray.push(tempADC);
  }
  return ADCarray;
}
Sign up to request clarification or add additional context in comments.

4 Comments

The problem with this approach is that I would have 11 objects all named tempADC, how do I get to an attribute about one of those 11? Using the example in the answer above: I want to know what is stored in the teacher attribute of the object that has Math stored in the department attribute.
tempADC is just the variable name. It has no influence on the object itself. If you were to look at the ADC array after this code, it would look something like this: [{name:"name1"},{name:"name2"},...{name:"name11"}].
right, so let's say I want to use the object with {name:"name1"} in another function and in that function I do a calculation and I want to store the result as a new attribute in the object with {name:"name1"}, how do I reference just that object to assign the new attribute? do I have to use the array index or can I somehow use the name attribute?
Let's say you want to add a teacher attribute to some object from the array. You could just do ADCarray[1].teacher = "teacher's name"; Then your object array would look like this [{name:"name1"},{name:"name2",teacher:"teacher's name"},...{name:"name11"}].
1

Object attributes can be assigned by dot notation, or the bracket notation (like Arrays)

So try this instead:

this[name] = name;

You wont then get a 'variable' of the department name, but the array of departments will be of objects with departments as attribute. Is this what you want, you potentially don't need the Array for loo if department names will always be unique.

Update

To expand on my point above about the non-need of the extra array. Because you are dealing with (I assume) unique department names, these can be the keys.

So:

function buildDepartments() {

  var departmentList = SpreadsheetApp.getActiveSpreadsheet().getRange('a1:c2').getValues(), // Assuming a 3 column list with, say: department name, department head, department deputy.
      departments = {},
      d;

  for (d = 0; d < departmentList.length; d += 1) {
    departments[departmentList[d][0]] = {head: departmentList[d][1], deputy: departmentList[d][2]};
  }

  // To recall the department details ... however many there are
  Logger.log(departments['Math'].head); // Logs the head of the Math department
}

but, it may make more sense to not tie yourself into keys that may change over time as if the department name changes it will be a hassle to make changes. It will also be easier to utilise ScriptDB if you 'despecify' the object. Thus:

function buildDepartments() {

  // Assuming a 3 column list with, say: name, head, deputy.
  var departmentList = SpreadsheetApp.getActiveSpreadsheet().getRange('a1:c2').getValues(), 
      departments = [], // Now this an array
      d;

  for (d = 0; d < departmentList.length; d += 1) {
    departments.push({
      title: departmentList[d][0],
      head: departmentList[d][1], 
      deputy: departmentList[d][2]
    });
  }

  // To recall the department details ... however many there are
  // Logs the head of the Math department by filtering the array to a single entry
  Logger.log(departments.filter(function (d) { return d.title = 'Math'; })[0]);
}

At this point, and to make things a little more intuitive on recall the departments array could be a constructor object once again. Thus:

function DepartmentList () {
  var list = [];
  this.addDepartment = function (dept) {
    list.push({ title: dept[0], head: dept[1], deputy: dept[2] });
    return this; // for chaining reasons, if you like.
  }
  this.getDepartment() = function(dept) {
    var foundDepartment = list.filter(function (d) { return d.title = dept; });
    return foundDepartment[0] || {}; // empty object if no department match
  }
  return list; // bare calls to the object returns the whole list
}

function buildDepartments () {
 var departments = SpreadsheetApp.getActiveSpreadsheet().getRange('a1:c2').getValues(),
     departmentList = new DepartmentList(), // Now this an object again
     d;

  departments.forEach( departmentList.addDepartment(entry) ); // Possible because GAS supports ECMAScript5 

  // To recall the department details ... however many there are
  // Logs the head of the Math department
  Logger.log(departmentList.getDepartment('Math').head);
}

The latter metod will only start to make sense if the input data is more extensive or needs any processing by object functions. This is probably overkill for my stated example.

4 Comments

In this case how would I pull out other attributes in the object using the department attribute as a reference? For example I need to know who the teacher of the Math department is.
you can dot chain on an array style call. Again, I think you can skip out one of the arrays here and just use a map object. therefore assuming a little bit of a rewrite (i may post a different answer) you would use ADC['math'].head
if I could have marked two answers as correct I would have because yours was also very helpful. thank you.
heh - just added big update ;) maybe overkill, but lots of learning about objects - upvotes also welcomed :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.