1

Considering the following Javascript code:

class Component {

  constructor() {
    /* ... */
    this.retrieveContentFromServer()
  }

  retrieveContentFromServer() {
    /* ... */
  }

}

class TextInput extends Component {

  constructor() {
    super()
    this.jqElmt = $('<input type="text" />')
    /* ... */
  }

  retrieveContentFromServer() {
    super.retrieveContentFromServer()

    console.log(this.jqElmt) // undefined
    // this.jqElmt.val(/* ... */)
  }

}

new TextInput()

The console.log(this.jqElmt) returns undefined when a new Object is created from TextInput, which is expected. My goal is to make it return the jQuery object created in the constructor, so that we can edit the text input content retrieved from a server.

So how can I change this piece of code so that:

  • Both the constructors of TextInput and Component are completely executed before any TextInput method is called
  • We are able to call a method from the Component constructor

I don't know if it's even possible...

Cinn
  • 4,281
  • 2
  • 20
  • 32
  • No, you should simply not call overridable methods from the constructor. Never, in no programming language. If you can tell us more about your use case (or show us your real code instead of a pseudo example), we can suggest an appropriate alternative. – Bergi Mar 02 '19 at 19:51
  • @Bergi i edited my question to present my use case. These are components of a web interface. – Cinn Mar 02 '19 at 20:28
  • Thanks, I see. `retrieveContentFromServer` is a network side effect, probably even asynchronous, that should *definitely* not be called from a constructor. Put it in a static method, as suggested in [my answer here](https://stackoverflow.com/a/47821096/1048572). Does that answer your question? If yes, I'll close as a duplicate. – Bergi Mar 02 '19 at 20:31
  • I wanted the component to automatically retrieve their content from server during their creation, so i cannot do that? I will have to do something like `const myInputText = new InputText(); myInputText.retrieveContentFromServer()` imperatively? – Cinn Mar 02 '19 at 20:42
  • @bergi - why is it a no go to call an overridable method from the constructor? Can you provide a link to an explanation? – mzedeler Mar 02 '19 at 20:53
  • It's a no go because, as you realised, it doesn't work. See the linked answer, and linked from there, [this question](https://stackoverflow.com/q/3404301/1048572) for a detailed explanation. – Bergi Mar 02 '19 at 20:55
  • Yes, this is imperative stuff, and should not go inside the constructor (whose only purpose is to initialise an object). You can however of course put it inside a helper function, to be called as `const myInputText = InputText.retrieveContentAndCreateInstance()` – Bergi Mar 02 '19 at 20:57
  • Thanks for these answers. I will probably better use different method names so the asynchronous one don't get overridden, then i don't have to do `const myInputText = InputText.retrieveContentAndCreateInstance()`. It sounds weird for me to systematically have to call the same method in the same way after each object creation. I see nothing wrong having an asynchronous process triggered from the constructor since this constructor does not wait for the answer to end, but i must be wrong... – Cinn Mar 02 '19 at 21:13
  • @Cinn You can trigger async stuff in the constructor (even if I would consider it bad style), but if you don't wait for it in the constructor that means you will have to wait for it everywhere else which is generally a nuisance. Doing it (or at least, being able to do it) separately from the constructor just gives better control. Additionally, triggering async stuff in the constructor through *overridable methods* just doesn't work, as established before. – Bergi Mar 03 '19 at 15:37

0 Answers0