0

I have two classes, a parent class and a child class that inherits from the parent class. When initializing the child class I call the constructor of the parent class with the super() keyword. Then I attempt to access the parent class variable in a child method. However, when I attempt to do this I receive this error: Cannot read property 'undefined'. Why is the variable undefined? Does the constructor not work as I expected it to?

    class Book {
      constructor(title, author, chapters) {
        this.title = title; //string
        this.author = author; //string
        this.chapters = chapters; //array of strings
      }
      getTitle() {
        return this.title;
      }
      getAuthor() {
        return this.author;
      }
    }
    class Chapter extends Book {
      constructor(title, author, chapters, numberPages, subject, time, chapterIndex) {
        super(title, author, chapters);
        this.numberPages = numberPages;
        this.subject = subject;
        this.time = time;
        this.chapterIndex = chapterIndex;
      }
      getChapterText() {
        return this.chapters[this.chapterIndex];
      }
    }

    var chapterOne = new Chapter("title", "author", ["lorem ipsum...", "lorem ipsum...", "lorem ipsum..."], 42, "about lorem ipsum", "3:01", 0); //book_object is an array of everything the chapter constructor needs
    console.log(chapterOne.getChapterText());

I've also tried using super.chapters to access the parent class variable, but I just got this error: unexpected keyword super.

Update

Maybe using ${book_object} made my question too confusing. This javascript is running as JSP (java server page). Therefore it's being compiled before being served. I updated my question to reduce confusion.

Update 2

    class Book {
      constructor(title, author, chapters) {
        this.title = title; //string
        this.author = author; //string
        this.chapters = chapters; //array of strings
      }
      getTitle() {
        return this.title;
      }
      getAuthor() {
        return this.author;
      }
    }
    class Chapter extends Book {
      constructor(title, author, chapters, numberPages, subject, time, chapterIndex) {
        super(title, author, chapters);
        this.numberPages = numberPages;
        this.subject = subject;
        this.time = time;
        this.currentChapter = this.getChapterText(); //I forgot to include this line in my original question.
        this.chapterIndex = chapterIndex;
      }
      getChapterText() {
        return this.chapters[this.chapterIndex];
      }
    }

    var chapterOne = new Chapter("title", "author", ["lorem ipsum...", "lorem ipsum...", "lorem ipsum..."], 42, "about lorem ipsum", "3:01", 0); //book_object is an array of everything the chapter constructor needs
    console.log(chapterOne.currentChapter);

I just realized that in my actual code (the code in this question is based on my actual code) I was calling my child class method in my child class constructor, and in that method I was trying to access my parent class variable. Here is a snippet of that. Turns out my issue was this all along. Would someone care to explain why this happens?

11
  • 3
    Why is Chapter a subclass of Book? A book can contain multiple chapters, so a chapter is not a kind of book. Commented Sep 26, 2018 at 20:23
  • When you call new Chapter() you don't provide the chapters argument, so it's undefined. So this.chapters = chapters sets it to undefined. The problem has nothing to do with accessing parent properties. Commented Sep 26, 2018 at 20:25
  • The way you've set this up, a Chapter is also a Book , just a special kind of book. There is no parent here to access. Commented Sep 26, 2018 at 20:25
  • @Barmar sorry, but it's not the case. The semantic does not matter, and, if you consider a book made by books, a chapter can sure be an book too. Commented Sep 26, 2018 at 20:26
  • What is ${book_object}? That's not valid syntax for a variable. It looks like the syntax used in template literals. Commented Sep 26, 2018 at 20:27

2 Answers 2

1

var chapterOne = new Chapter(${book_object}); //book_object is an array of everything the chapter constructor needs

The constructor you've defined expects a comma separate sequence of title, author, chapters, numberPages, etc. As long as you pass that in, things will work. But if you're passing in an object or array like you describe, then that's just a single parameter, which will be the "title" parameter in the constructor. The remaining parameters are undefined.

So either change your constructor to expect the object you're passing in, or change the way you call the constructor

const chapterOne = new Chapter('some title', 'some author', ['chapter1', 'chapter2'], 42, /*etc*/);

If ${book_object} is an actual array, which happens to have the parameters in the right order, you could use the spread operator to turn it into the list of arguments:

const bookArray = [
  'some title', 
  'some author', 
  ['chapter1', 'chapter'2],
  42
  // etc
]
const chapterOne = new Chapter(...bookArray);
Sign up to request clarification or add additional context in comments.

1 Comment

Maybe using ${book_object} made my question too confusing. This javascript is running as JSP (java server page). Therefore it's being compiled before being served. I updated my question to reduce confusion.
1

If book_object is an array of the parameters needed by the contructor, you need to spread it. The correct syntax is ...variable, not ${variable}.

var chapterOne = new Chapter(...book_object)

Comments

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.