Home > Software engineering >  Extending express-js in a ES-6 class: trouble binding getter and setter
Extending express-js in a ES-6 class: trouble binding getter and setter

Time:01-21

It is of my interest to work with Express in a extended class. I want to define a getter and setter for a property, but doing so will not bind the methods to the instances. A workaround is to create a custom getter and setter method and binding it on the constructor, but it feels wrong.

const express = require("express");


export default class Application extends express {
    _endpoints;

    constructor() {
        super();
        this._endpoints = null;
    }
    get endpoints() {
        return this._endpoints;
    }

    set endpoints(paths: []) {
        this._endpoints = new Set(...paths);
    }
}


const myApp = new Application();
console.log(myApp) // ...express-app-object, _endpoints, and nothing related to the getter and setter defined.
console.log(myApp._endpoints) // null
console.log(myApp.endpoints) // undefined

CodePudding user response:

It apparently has to do with the fact that express is not a class or a constructor, it's a factory function. When you call super(), it calls express() and that creates a whole new object, that is not your object and does not have your prototype. Referencing myApp._endpoints works because your constructor assigned that property in your constructor to the object that express() created, but that object does not have your prototype attached to it, it's a new object that Express created.

If you remove the extends express from your code and comment out the super(), you will see that it all works.

If you change express to any other actual defined class in Javascript, your endpoints() getter works just fine.

So, you can't extend express in this manner.

The express prototype is available and you can add things to it the way we used to before we had the class keyword.

CodePudding user response:

export class Application extends express {
    private _endpoints = null;

    constructor() {
        super();
        Object.defineProperty(this, "endpoints", {
            get: function () {
                return this._endpoints;
            },
            set: function (paths: any[]) {
                this._endpoints = new Set([...paths]);
            },
            enumerable: true,
            configurable: true,
        });
    }
}

Usage would be normal:

const app = new Application();
console.log(app.endpoints) // null
app.endpoints = ['/auth/signin', '/auth/signout']
console.log(app.endpoints) // Set(2) { '/auth/signin', '/auth/signout' }
  •  Tags:  
  • Related