Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overidding library function in es6

Tags:

I'm trying to override specific function in a library. In my case, I'm trying to override some functions on Framework7. The library simply has class called Framework7, in non ES6 javascript, creating instance of application would look like this:

var app = new Framework7();

so I assume it's extendable, so here my code to extends it:

export class Application extends Framework7 {
    constructor(options) {
        super(options);
    }
}

the code run fine, however, when I try to override one of the function, let say showPreloader, the function itself is never called

export class Application extends Framework7 {
    constructor(options) {
        super(options);
    }

    showPreloader(title) {
        console.log('this not printed :(');
        super(title); // this is not called as well

        // but showPreloader() from Framework7 still called
    }
}

I also try different approach to override it, i come with a solution like this:

export class Application extends Framework7 {
    constructor(options) {
        super(options);

        this.showPreloader = (title) => {
            console.log('print me!'); // printed! :D
            super(); // oh, wait! cannot call super from here! :(
        }
    }
}

However, it looks a bit ugly and I cannot call super from there.

Is there any workaround so I can override a function from library and calling the base function via super (or anything?)

like image 704
CXO2 Avatar asked Aug 10 '16 11:08

CXO2


1 Answers

I assume it's extendable

Don't. Read the docs, ask the authors, or read the source yourself.

In your case, the library you've chosen doesn't exactly follow best practises, it just installs its methods directly on the app "instance". It's a factory function, not a constructor.

Is there any workaround so I can override a function from library and calling the base function?

Yes, by storing the original method in a variable before overwriting it. You then can call it using .call(this) (like inheritance was done in ES5).

…
    const original = this.showPreloader;
    this.showPreloader = (title) => {
        console.log('print me!'); // printed! :D
        original.call(this, title);
    }

However, that's no fun, especially since it's not just a few instance-specific methods but actually all of them. So you'd better drop ES6 class syntax and "subclassing" here, and use a parasitical inheritance approach instead:

function MyFramework7(options) {
    const app = new Framework7(options);
    const {showPreloader, …} = app; // all the original methods
    … // mess with the object to your liking
    return app;
}

Or maybe you don't even need to wrap it in a function, as app is a singleton I guess.

like image 147
Bergi Avatar answered Sep 26 '22 16:09

Bergi