Please help with project School library in JS: Classes


#1

Link to project
Can you help with task 5?

Create a setter for numberOfStudents. The method should first check if the input (newNumberOfStudents) is a number. If it is a number, then set the numberOfStudents property. If not, log, ‘Invalid input: numberOfStudents must be set to a Number.’

Use the following syntax to create a setter that checks the type of an input.

Syntax
set myProperty(newMyProperty) {
  if (typeof newMyProperty === 'String') {
    this._myProperty = ...
  } else {
    ...
  }
}

I made this, but it doesn’t check newNumberOfStudents === ‘number’.

My setter
  set numberOfStudents(newNumberOfStudents) {
    if (typeof newNumberOfStudents === 'number') {
      this._numberOfStudents = newNumberOfStudents;
    } else {
      console.log('Invalid input: numberOfStudents must be set to a Number.');
    } 
  }
All code
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(newNumberOfStudents) {
    if (typeof newNumberOfStudents === 'number') {
      this._numberOfStudents = newNumberOfStudents;
    } else {
      console.log('Invalid input: numberOfStudents must be set to a Number.');
    } 
  }
  
  quickFacts() {
    console.log(`${this.name} educates ${this.numberOfStudents} students, typically between the ages of ${this.level}.`);
  }
  
  static pickSubstituteTeacher(substituteTeachers) {
    this.substituteTeachers = [];
    let randomTeacher = Math.floor(substituteTeachers.length * Math.random());
    this.substituteTeachers = substituteTeachers[randomTeacher];
    //console.log(`${this.substituteTeachers}`); // it works!
  }
}

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

class HighSchool extends School {
  constructor(name, numberOfStudents, sportsTeams) {
    super(name, 'high', numberOfStudents);
    this._sportsTeams = sportsTeams;
  }
  
  get sportsTeams() {
    //console.log(`${this._sportsTeams}`); // it works!
    return this._sportsTeams;
  }
}

const lorraineHansbury = new PrimarySchool('Lorraine Hansbury', 'fd', 'Students must be picked up by a parent, guardian, or a family member over the age of 13.');
lorraineHansbury.quickFacts();
School.pickSubstituteTeacher(['Jamal Crawford', 'Lou Williams', 'J. R. Smith', 'James Harden', 'Jason Terry', 'Manu Ginobli']);

const alSmith = new HighSchool('Al E. Smith', 415, ['Baseball', 'Basketball', 'Volleyball', 'Track and Field']);
console.log(`${School.substituteTeachers}`);

console.log(`${alSmith.sportsTeams}`);

#2

Is this giving you an error, or is the SCT not accepting it?

In my code I used the unary operator to cast a number, if possible…

if (+number) { ... }
alSmith.numberOfStudents = `415`;
console.log(alSmith.numberOfStudents);
alSmith.numberOfStudents = 'four';
415
Invalid input: numberOfStudents must be set to a Number.

#3

The code is executed without errors, but I can’t receive this error message - ‘Invalid input: numberOfStudents must be set to a Number.’. When I add string value for numberOfStudents, I have it.

alSmith.numberOfStudents = 'Any string';
console.log(alSmith.numberOfStudents);

Result: Invalid input: numberOfStudents must be set to a Number.

But when I change 250 to ‘Any string’, I do not receive error message.

const alSmith = new HighSchool('Al E. Smith', 250, ['Baseball', 'Basketball', 'Volleyball', 'Track and Field']);
alSmith.quickFacts();

Result: Al E. Smith educates Any string students, typically between the ages of high.


#4

Are you testing inside the function?

if (typeof newNumberOfStudents === ‘number’)
 > typeof '101'
=> 'string'
 > typeof +'101'
=> 'number'

#5

Outside, in the bottom of program.


#6

Can you re-post your numberOfStudents setter?


#7
  set numberOfStudents(newNumberOfStudents) {
    if (typeof newNumberOfStudents === 'number') {
      this._numberOfStudents = newNumberOfStudents;
    } else {
      console.log('Invalid input: numberOfStudents must be set to a Number.');
    } 
  }

#8

I don’t see any errors in your code and cannot fathom why a string would get through. Perhaps try using the unary and see what happens.

if (+newNumberOfStudents) {

} else {

}

#9

I changed if/else, but it didn’t help :persevere:

Short code
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(newNumberOfStudents) {
    if (+newNumberOfStudents) {
      this._numberOfStudents = newNumberOfStudents;
    } else {
      console.log('Invalid input: numberOfStudents must be set to a Number.');
    }
  }
  
  quickFacts() {
    console.log(`${this.name} educates ${this.numberOfStudents} students, typically between the ages of ${this.level}.`);
  }
}

const school = new School('Alex', 'Level of School', '<Should be number, but I put string and did not receive error message>');
school.quickFacts();
console.log(school.numberOfStudents);

Result: Alex educates <Should be number, but I put string and did not receive error message> students, typically between the ages of Level of School.
<Should be number, but I put string and did not receive error message>

So, the problem is: Why it is possible add string in values only for numbers?


#10

That is because the value you pass is given immediately to the property. There is no checking by the constructor. The method only checks when we manually run the setter.


#11

And I don’t know how to fix that.


#12

Nothing to fix. Just be sure to pass in the correct value when you invoke a new instance.


#13

Ok, I get it. Thank you!