1

I have some javascript code which looks like this - it's very repetitive, and as you can see follows a very defined pattern:

var AttachmentBuilder = function(){
    this.attachment = {};
}
AttachmentBuilder.prototype.text = function(value){
    this.attachment.text = value;
    return this;
}
AttachmentBuilder.prototype.fallback = function(value){
    this.attachment.fallback = value;
    return this;
}
 AttachmentBuilder.prototype.color = function(value){
    this.attachment.color = value;
    return this;
}

I had the idea to refactor this like:

var AttachmentBuilder = function(){
    this.attachment = {};
}
passThrough(AttachmentBuilder.prototype,"attachment","text");
passThrough(AttachmentBuilder.prototype,"attachment","fallback");
passThrough(AttachmentBuilder.prototype,"attachment","color");

function passThrough(obj, apply, name){
    obj[name] = function(param){
        this[apply][name] = param;
    }
    return this;
 }

But the context of this is not correct, and it does not behave like the long-hand version.

Below is a working example demoing the working and not working versions.

var AttachmentBuilder_Original = function(){
    this.attachment = {};
}
AttachmentBuilder_Original.prototype.text = function(value){
    this.attachment.text = value;
    return this;
}
AttachmentBuilder_Original.prototype.fallback = function(value){
    this.attachment.fallback = value;
    return this;
}
 AttachmentBuilder_Original.prototype.color = function(value){
    this.attachment.color = value;
    return this;
}

var original = new AttachmentBuilder_Original();
original.text("Text").color("Red").fallback("Fallback");
console.log("original",original.attachment);

/* ------------------------------------- */

var AttachmentBuilder_New = function(){
    this.attachment = {};
}
passThrough(AttachmentBuilder_New.prototype,"attachment","text");
passThrough(AttachmentBuilder_New.prototype,"attachment","fallback");
passThrough(AttachmentBuilder_New.prototype,"attachment","color");

function passThrough(obj, apply, name){
    obj[name] = function(param){
        this[apply][name] = param;
    }
    return this;
}

var adjusted = new AttachmentBuilder_New();
adjusted.text("Text").color("Red").fallback("Fallback");
console.log("adjusted",adjusted.attachment);

I'm also interested if there is a more ES6-like way of solving this same issue of repetition.

3
  • You meant return this inside function? Commented Apr 28, 2017 at 10:22
  • It is high time to code in es6 and use a transpiler+bundler for es5 support. Can save you from these hurdles and focus on business logic. Just a suggestion. Commented Apr 28, 2017 at 10:27
  • And it is a nodeJS project so ES6 away! Commented Apr 28, 2017 at 10:27

2 Answers 2

2

Your higher order function looks good. Probably simple mistake of putting return statement in the wrong place.

function passThrough(obj, apply, name){
    obj[name] = function(param){
        this[apply][name] = param;
        return this;
    } //^^^^^^^^^^^^
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for calling me a n00b. Ive only been writing javascript for 25 years! But indeed - I had my return this in the wrong place.
Hmm its probably bad language use. Not that proficient in the language, this happens all the time. I meant simple mistake, sorry if that was bad.
S'ok. If you have a more ES6-like solution to this problem Im most interested. I am still stuck in old-fashioned JS thinking
I don't think es6 has anything special related to chaining so I'll better take back my free opinion on this. If I find anything related to this pattern I'll update here.
0

Your solution should work, if you do this modification.

var AttachmentBuilder = function(){
        this.attachment = {};
    }
    passThrough(AttachmentBuilder.prototype,"attachment","text");
    passThrough(AttachmentBuilder.prototype,"attachment","fallback");
    passThrough(AttachmentBuilder.prototype,"attachment","color");

    function passThrough(obj, apply, name){
        obj[name] = function(param){
            this[apply][name] = param;
            return this;//<---move return this here
        }
        //return this;
     }

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.