School Catalogue Project

Hi guys ! First Post on here :wink:
I have a bit of a struggle with this exercice and I don’t understand why… I watched the tutorial and read a few topics but I cant still figuring out. I’d appreciate some advice ! :smiley:
The thing is when I console.log(lorraineHansbury), everything seems fine but I get some undefined on lorraineHansbury.quickFacts().


//                SCHOOL == parent class              //
class School {
  constructor(name, level, numberOfStudents){
    this._name = name;
    this._level = level;
    this._numberOfSutdents = numberOfStudents
  }

  get name() {
    return this._name
  }
  get level() {
    return this._level
  }
  get numberOfStudents() {
    return this._numberOfStudents
  }
  
  set numberOfStudents(newNumberOfStudents){
    if(newNumberOfStudents.typeOf === '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 at the ${this.level} school level.`)
  }

  static pickSubstituteTeacher(substituteTeachers) {
    const randomTeacher = Math.floor(substituteTeachers.length * Math.random());
    return substituteTeachers[randomTeacher];
  }
}

                          // PRIMARY SCHOOL CLASS // 
class PrimarySchool extends School {
  constructor(name, numberOfStudents, pickupPolicy) {
    super(name,'primary', numberOfStudents);
    this._pickupPolicy = pickupPolicy;
  }


  get pickupPolicy() {
    return this._pickupPolicy
  }
};

                            // HIGH SCHOOL CLASS //
class HighSchool extends School {
  
  constructor(name, numberOfStudents, sportsTeams) {
    super(name, 'high', numberOfStudents);
    this._sportsTeams = sportsTeams;
  }
  
  
  get sportsTeam() {
    return this._sportsTeams
    console.log(this._sportTeams)
  }
}

                      // INSTANCES //
const lorraineHansbury = new PrimarySchool('Lorraine Hansbury', 514, 'Students must be picked up by a parent, guardian, or a family member over the age of 13.');
lorraineHansbury.quickFacts();
console.log(lorraineHansbury);


Hi @tag9358347230
Welcome to the forum!
You already found out that your getter numberOfStudents returns undefined by logging the quick facts. Trace the key back to the constructor of the parent class to find out why it doesn’t get the value…

1 Like

Thank you ! I feel silly haha Guess I spent to much time doing this today, couldnt see the bigger picture anymore… Thx

1 Like

You made a typo.

class School {
constructor(name, level, numberOfStudents){
this._name = name;
this._level = level;
this._numberOfSutdents = numberOfStudents
}

Should be ‘this.numberOfStudents’ instead of ‘this._numberOfSutdents’.
Hope it helps.

Hello,

Great excercise!

If I enter a string for numberOfStudents, I don’t get the warning from “isNaN.” I’ve reviewed my code multiple times but I can’t find the bug.

What am I doing wrong?

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(value) {
        if (value.isNaN()) {
            console.log(`Invalid input: numberOfStudents must be set to a Number.`)
        } else {
            return this._numberOfStudents = value;
        }
    }

    quickFacts() {
        console.log(`${this.name} educates ${this.numberOfStudents} students at the ${this.level} school level.`)
    }

    static pickSubstituteTeacher(substituteTeachers) {
        const randInt = Math.floor(Math.random() * substituteTeachers.length);
        return substituteTeachers[randInt];
    }
}

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() {
        return this._sportsTeams;
    }
}

const lorraineHansbury = new PrimarySchool('Lorraine Hansbury', "forty", '4pm')

console.log(lorraineHansbury.name)
console.log(lorraineHansbury.numberOfStudents)
console.log(lorraineHansbury.pickupPolicy)

lorraineHansbury.quickFacts()

School.pickSubstituteTeacher([
    'Jamal Crawford',
    'Lou Williams',
    'J. R. Smith',
    'James Harden',
    'Jason Terry',
    'Manu Ginobli']);

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

alSmith.quickFacts()

console.log(alSmith.sportsTeams)

Three things to observe here:

  1. You do not use the setter anywhere as far as I can see. This is how you would use it (if you want to test the type check and get the error log):
    alSmith.numberOfStudents = '30'
  2. isNan() is not a property/method of value. This would be the correct syntax:
    if (isNaN(value))
  3. Not everything that is not a number is NaN. Check for typeof value like so:
    if (typeof value !== 'number')
1 Like

Hi @mirja_t,

I appreciate your time and response.

I did the changes like this:

 set numberOfStudents(value) {
        if (isNaN(value)) {
            console.log(`Invalid input: numberOfStudents must be set to a Number.`)
        } else {
            return this._numberOfStudents = value;
        }
    }

At the bottom of my js file, If I enter text this:

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

Notice that instead of a number I entered a string ‘hola’, and I get this result:

Al E. Smith educates hola students at the high school level.

Shouldn’t it tell me that ‘hola’ is not a number?

Thank you for your time.

No. The instance of the Highschool class (new HighSchool()) omits the setter. That is done directly inside the constructor.
If you use the state setter after the instanciaton like this:

alSmith.numberOfStudents = 'hola'

you’ll see the error message.

1 Like

Hi @mirja_t

Ah, I see the error message with:

alSmith.numberOfStudents = 'hola'

So, why would the new instance ignore the setter? Isn’t that what the setter is for? Or what is the best way to add a new record with name, number of students, and teams that don’t omit their setters?

I’m super new to this topic, as you can tell.

Thank you for your time.

1 Like

You would write a setter to increase the usability of your class for external use. For people, who did not write that class, it makes the use of your class more understandable.
You could call a method of your class in the constructor as well, like this:

class School {
    constructor(name, level, numberOfStudents){
        this._name = name;
        this._level = level;
        this._numberOfStudents = this.typeCheckNumber(numberOfStudents);
    }
    typeCheckNumber(num) {
    	if (isNaN(num)) {
            console.log(`Invalid input: numberOfStudents must be set to a Number.`)
            return 0
        } else {
            return num;
        }
    }
}

That would log an error message on instanciation already.

Hi @mirja_t,

Thank you for taking the time to write all the code in your answer. It clears my initial confusion. I will try your code tonight for sure.

A very simple question, does it matter the order of the setters and getters? For example, does the getter need to be before the setter or vice-versa?

get someGetter() {
    return this._someGetter

set someSetter() {
    return this._someSetter

Or can they be reversed in order?

set someSetter() {
    return this._someSetter

get someGetter() {
    return this._someGetter

Thank you again @mirja_t

1 Like

As a convention, you would write the getter before the setter.
Both works, though:

class Person {
    constructor(name){
        this._name = name;
    }

    set name(name) {
        this._name = name;
    }
    
    get name() {
        return this._name;
    }
}

const john = new Person('John')
console.log(john.name) // John
john.name = 'Jane'
console.log(john.name) // Jane
1 Like