0

I have the following javascript class and for some reason the current property is not being set to -1 when i'm done loading the records (or i'm not able to access the property correctly from an instance of the class). I'm new to javascript so any help would be appreciated.

var MyLib = function () {
this.current = 0;

MyLib.prototype.loadMore = function (id, loadingDivId, url) {
    if (this.current > -1) {
        this.current++;
        $(loadingDivId).html("<h3>Loading more records please wait...</h3>");
        $.get(url + this.current, function (data) {
            if (data != '') {
                $(id).append(data);
                $(loadingDivId).empty();
            } else {
                this.current = -1; // seems like this isn't being set
                $(loadingDivId).html("<h3><i>-- No more results -- </i></h3>");
            }
        });
    }
}

};

Here's how i'm calling it

<script type="text/javascript">
     $(function () {
         var lib = new MyLib();

         $('#loadMore').click(function () {
             if (lib.current > -1) {
                 lib.loadMore("#results", "#loading", '/home/search/');
                 if (lib.current == -1) { 
                     // Having problems getting into this portion
                     $("#loadMore").hide();
                 }

             }
             return false;
         });

     });

</script>
zSynopsis
  • 4,854
  • 21
  • 69
  • 106
  • I can't test AJAX stuff very easily right now; did you check to make sure that the `data` argument exists? My guess is your if/else is failing, and it's resetting `this.current` to -1. – sdleihssirhc Jan 28 '11 at 18:07
  • i don't thick data is the issue since i see the "No more results found" being set. – zSynopsis Jan 28 '11 at 18:11
  • I updated [my answer](http://stackoverflow.com/questions/4831519/javascript-property-accessing-issues/4831604#4831604). I think I had the callback function in the wrong spot at first. – user113716 Jan 28 '11 at 18:25
  • This is the same question as today's: http://stackoverflow.com/questions/4828695/setting-members-of-object-using-function-fails/4828754 – Ned Batchelder Jan 28 '11 at 18:06

2 Answers2

1

prototypes go out side the function declaration

var MyLib = function () {
this.current = 0;
};

MyLib.prototype.loadMore = function (id, loadingDivId, url) {
    if (this.current > -1) {
        this.current++;
        $(loadingDivId).html("<h3>Loading more records please wait...</h3>");
        $.get(url + this.current, function (data) {
            if (data != '') {
                $(id).append(data);
                $(loadingDivId).empty();
            } else {
                this.current = -1; // seems like this isn't being set
                $(loadingDivId).html("<h3><i>-- No more results -- </i></h3>");
            }
        });
    }
}
Jake Kalstad
  • 2,045
  • 14
  • 20
  • There is nothing or nobody prescribing prototype methods can't be added within the constructor function. – KooiInc Jan 28 '11 at 18:19
  • 1
    @Kooilnc, you can assign prototype members within the constructor but it doesn't make much sense. If you do so, the assignment will be done *each time* the constructor function is invoked, that can create even more confusion if they try to use *in-scope* variables of the constructor variable environment, as an example of this kind of problems, check this question: [Setting javascript prototype function within object class declaration](http://stackoverflow.com/questions/2784844/) – Christian C. Salvadó Jan 28 '11 at 18:30
  • @Kooilnc, the problem I was talking about, regards with the scope chain, for example, if you want to access a local variable of the constructor, on a method added on its `prototype`, e.g.: http://jsfiddle.net/fCVUw/2/ you will see how the scope remains bound at the time the function was created (first execution), I don't really see any advantage on assigning prototype members (specially functions) within the constructor itself. This example is what I think can create confusion... – Christian C. Salvadó Jan 28 '11 at 19:19
  • @CMS My fiddle was only to demonstrate the **possibility** of adding prototypal methods within the constructor. Your fiddle demonstrates something that also wouldn't work in a prototypal method created outside a constructor function. Javascript is a very flexible language. It's resistant to semi-evangelistic statements like *prototypes go outside the function declaration* etc. You can even declare a prototype method-adding method in the constructor prototype inside the constructor, why not? See: http://jsfiddle.net/fCVUw/3. – KooiInc Jan 28 '11 at 20:00
  • @Kooilnc, yep, agree with you (I don't like either evangelistic statements ;), also I never said it wasn't possible :), I only said that IMHO you don't gain almost anything by doing it, e.g., in your last fiddle, `proto.getName` is never executed, because it's always *shadowed* by `this.getName`. – Christian C. Salvadó Jan 28 '11 at 20:50
  • @CMS, glad you agree. Anyway, there are usages for declaratrion of prototype methods within the constructor, for example if you want to use fixed values (sort of readonly/constants) within your constructor, like in http://jsfiddle.net/Dja5n/2/. Anyway, it's save to say that the idea of *prototypes go outside the function declaration* is not that absolute, right? – KooiInc Jan 28 '11 at 22:38
  • you CAN put them in the constructor, but they simply DO NOT go there, make a factory and slap on a prototype if its undefined or something of that kin, either way the key of my quote was to simply say -> 'prototypes go out side the function declaration' – Jake Kalstad Jan 28 '11 at 23:24
  • 1
    @Gnostus, my point is to say that *prototypes go outside the function declaration* is too simple. They can go there and sometimes they DO go there, if you like it or not. One relief: *you* don't have to put them there. Here's one vote for the freedom of prototypal-method-positioning. Cheerz! – KooiInc Jan 28 '11 at 23:34
1

While @Gnostus is correct about the prototype placement, you have an issue because you're making an asynchronous request, but are attempting to use the response immediately after sending the request.

In other words, the code after your loadMore() call runs before the response is received.

Change your prototype to accept a function to be used in the callback.

   // accept a function to call upon success ---------------v
MyLib.prototype.loadMore = function (id, loadingDivId, url, fn) {
    if (this.current > -1) {
        this.current++;
        $(loadingDivId).html("<h3>Loading more records please wait...</h3>");
        $.get(url + this.current, function (data) {
            if (data != '') {
                $(id).append(data);
                $(loadingDivId).empty();
            } else {
                this.current = -1; 
  // ------------v------call the function
                fn();
                $(loadingDivId).html("<h3><i>-- No more results -- </i></h3>");
            }
        });
    }
}

Then pass in the functionality that relies on the response.

$('#loadMore').click(function () {
     if (lib.current > -1) {

             // pass in your function -----------------------------v
         lib.loadMore("#results", "#loading", '/home/search/', function() {
                  // This if() statement could be removed, since it will
                  //    always be "true" in the callback. 
                  // Just do the $("#loadMore").hide();
              if (lib.current == -1) { 
                    $("#loadMore").hide();
              }
         });
     }
     return false;
 });

Or if this will be standard functionality, you could add the function to the prototype of MyLib, and just have it accept the relevant arguments. Then your loadMore can simply call it from this.

user113716
  • 318,772
  • 63
  • 451
  • 440