Help With School Catalog

Hey there I was wondering if you had time to help me with the school catalog as well. Everything seems to be working fine, except my setter method. It won’t check to see what’s passed in and return an error if the wrong data type has been entered:

class School {
  constructor(name, level, numberOfStudents) {
    this._name = name;
    this._level = level;
    this._numberOfStudents = numberOfStudents;
  }
  
  get name() {
    return this._name
  }
  
  get level() {
    return this._level
  }
  
  get numberOfStudents() {
    return this._numberOfStudents;
  }
  
  set numberOfStudents(num) {
    if (typeof num === 'number'){
      this._numberOfStudents = num
    } else {
      console.log('Invalid input!')
    }
    
  }
  
  quickFacts() {
    console.log(`${this.name} educates ${this.numberOfStudents} students at the ${this.level} school level.`);
  }
  
  static pickSubstituteTeacher(substituteTeachers) {
    substituteTeachers = ['', '', ''];
    let randomIndex = Math.floor(Math.random() * substituteTeachers.length);
    return substituteTeachers[randomIndex];
  }
};

class Primary extends School {
  constructor(name, numberOfStudents, pickupPolicy) {
    super (name, 'primary', numberOfStudents)
    this._pickupPolicy = pickupPolicy;
  }
  
  get pickupPolicy() {
    return this._pickupPolicy;
  }
};

class Middle extends School {
  constructor(name, numberOfStudents) {
    super(name, 'middle', numberOfStudents)
  }
};

class High extends School {
  constructor(name, numberOfStudents, sportsTeams) {
    super(name, 'High', numberOfStudents)
    this._sportsTeams = sportsTeams;
	}
  
  get sportsTeams() {
    return this._sportsTeams
  }
};

let test = new Middle('SMCS', 'hey', 'pickup policy is stupid');

console.log(test.numberOfStudents);

in the case where im testing the instance at the end, passing in ‘hey’ as the second argument should return an error but it still gets passed in somehow. Any help with this would be greatly appreciated!

1 Like

Too many arguments for MIddle. Change that to Primary.

1 Like

Yea I had it there in primary as well, I just moved it to secondary to see if the setter would work but it still makes no difference.

For some reason the setter isnt return the string “invalid input” when i pass in “hey” even though its supposed to check if it’s a number

1 Like

Even like this:

let test = new Primary('smdy', 'hey', 'pickup policy is stupid');

console.log(test.numberOfStudents);

it’s still passing in ‘hey’ as the number of students

1 Like

The setter is not running because the classs is instantiated with the arguments given, that without checking.

The following will check the inputs (by using the setter) when the instance is created…

this._numberOfStudents = this.numberOfStudents(numberOfStudents);

It means the attribute will be undefined if it is given faulty inputs. Try it and let me know what happens.

1 Like

Sadly it didn’t work and returned an error:

TypeError: this.numberOfStudents is not a function

1 Like

Okay, did you play around with it?

this.numberOfStudents = numberOfStudents;
1 Like

Yea I tried removing a couple things, moving around the order as to what seems logical, it really is completely stumping me. Up to here I had to problem with the getter setters but this just seems to be some finicky small detail. I’ve also tried recoding it in atom with a much simpler class to play around and it seems that if else statements arent taking in the setter

1 Like

Well I found a way to get it to work but it is totally unexpected, maybe you can explain this to me.

When I write:

set _numberOfStudents(num) {....}

It all of a sudden starts working. Am I missing something or is the whole point of a setter to not use the prepended underscore property?

nevermind that gives me a stack overflow

Please post a link to the exercise. Thanks.

Follow this pattern…

class School {
    constructor(nos) {
        this.nos = nos;    // uses the setter to check the argument
    }
    get nos () {
        return this._nos;
    }
    set nos (n) {
        if (+n) {
            this._nos = n;
        } else {
            console.log("Error");
        }
    }
}

a = new School('hey')
Error
a.nos
undefined
b = new School(42)
b.nos
42
1 Like
1 Like

If we wish to use the setter to check inputs,

this.numberOfStudents = numberOfStudents;

No underscore on this one. The setter will create the attribute if it does not exist.

1 Like

Beautiful, is that only for setter properties or for ones that I used getters on?

1 Like

It’s very contrived, and not what one expects when reading from the top down. What looks like a plain attribute assignment is actually a series of method calls that take place in the background.

this.numberOfStudents

is a call to the getter, and once there is a binding on the backing variable, it proceeds to call the setter with the assigned value.

Much has been written about ES6’s implementation of setters and getters, not all of it good, and for good reason. For clarity, think in terms of plain objects and how we might do all this without s/g’s.

While we won’t see the above pattern very often, it has one redeeming quality… Validating arguments at the very time the instance is created.

We cannot use setters on attributes that do not have getters. The reverse is not the case. Getters do not depend upon setters and if there is no need to set an attribute, don’t give it a setter.

Addendum

There are two ways of looking at getters. Above we use it in the pure sense… retrieve a value, or as in the case of setters, invoke a binding. The latter of the two may be tricky if we don’t return the actual attribute value from the getter.

As mentioned, if we don’t need a setter, don’t have one. That leaves the door open for option number two, string representation. If we manually retrieve/reset the attribute, then the getter can dress it up a little on the return.

get name () {
    return `The member presents as, ${this._name}.`;
}

Post Addendum

if (+n)

Only two things can come from +n: A number, or NaN. We use a unary operator to cast a number and if it fails it responds with what means, Not a Number. Call it a cheat method of testing for a number, though we’re not really cheating, just using an operator that JS has given us for this very purpose.

As operations go, there has to be an outcome and + acting on its own forces one. N or NaN. There is something to be said of whomever dreamt this one up. I love it.

2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.