11

I need to fix a bug in the save function of the Parse.Object library. However, when I try to call the original save function in my overwritten prototype, it loops recursively until the stack overflows!

Parse.Object.prototype.save = function (arg1, arg2, arg3) {
    fixIncludedParseObjects(this);

    Parse.Object.prototype.save.call(this, arg1, arg2, arg3); // endless loop
};

How can I change the endless loop line to call the original function made by parse?

Thanks!

Garrett
  • 11,451
  • 19
  • 85
  • 126
  • I LOVE this question but still can't find an answer that works for me, even with the answer from @xdazz. – Ryan Jan 29 '17 at 20:26

3 Answers3

24

Try this:

(function(save) {
  Parse.Object.prototype.save = function (arg1, arg2, arg3) {
    fixIncludedParseObjects(this);
    save.call(this, arg1, arg2, arg3);
  };
}(Parse.Object.prototype.save));
xdazz
  • 158,678
  • 38
  • 247
  • 274
  • 4
    Can you please explain what's going on here? Or some link which does. Thanks – Adi Jul 08 '12 at 07:48
  • 3
    @Adnan You need to save the old save method to a variable, in this way, use the function parameter `save`. – xdazz Jul 08 '12 at 07:52
  • I appreciate this answer but cannot figure out how to get it to work in this case where my original function (`Survey.SurveyPage.prototype.render`) has a bunch of references to `this`. Because I assume "this" changes. So I wonder how I can change my attempt of extending it here: `(function (originalFunction) { Survey.SurveyPage.prototype.render = function () { originalFunction.call(this); }; }(Survey.SurveyPage.prototype.render));` – Ryan Jan 29 '17 at 20:28
  • 1
    I found a blog post that pointed me in the right direction and inspired this, which seems to do what I was hoping for: `Survey.SurveyPage.prototype.render = (function (_super) { return function () { beforeSurveyPageRender(); var origResult = _super.apply(this, arguments); afterSurveyPageRender(); return origResult; }; })(Survey.SurveyPage.prototype.render);//http://jondavidjohn.com/extend-javascript-functions/` – Ryan Jan 30 '17 at 02:20
  • 1
    For those confused at the slightly bizarre-looking function wrapping going on here, this answer was written in 2012 when IIFEs were apparently all the rage. See Below the Radar's answer for a more readable version, and this StackOverflow post explaining IIFEs: https://stackoverflow.com/a/8228308/ – WD40 Apr 28 '19 at 15:18
10

Similar to accepted answer but maybe a little easier to understand

var originalSaveFn = Parse.Object.prototype.save;
Parse.Object.prototype.save = function(arg1, arg2, arg3) {
    fixIncludedParseObjects(this);
    originalSaveFn.call(this, arg1, arg2, arg3);
};
Below the Radar
  • 7,321
  • 11
  • 63
  • 142
7
Parse.Object.prototype.save = function (save) {
    return function () {
        fixIncludedParseObjects(this);
        //Remember to return and .apply arguments when proxying
        return save.apply(this, arguments);
    };
}(Parse.Object.prototype.save);
John Slegers
  • 45,213
  • 22
  • 199
  • 169
Esailija
  • 138,174
  • 23
  • 272
  • 326
  • 1
    Works, but gives the JSHint error "Wrap an immediate function invocation in parentheses" https://jslinterrors.com/wrap-an-immediate-function-invocation-in-parentheses – Benjamin Intal Dec 31 '15 at 03:49