1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

ajax and callbacks

Discussion in 'jQuery' started by Jeremy Benson, Apr 3, 2017.

  1. #1
    I'm having a bit of trouble with ajax and callbacks. Seems I can never learn this, lol.

    The following code is in my main game window, which is a browser client.

    I call set character, which just fetches character name from DB. The .done callback in jquery seems to only fire one part.

    $(document).ready(function(){
      
    
                var Parser = new CommandParser();
                var OutputObj = new Output();
                var Traveler = new CharacterTraveler();
                var CharacterObj = new Character();
              
                CharacterObj.set_name();
              
                $("#maininput").on("input propertychange", function(){
                  
                    var val = $('#maininput').val();
                    Parser.update(val);
                  
                });
              
                $("#inputsubmit").click(function(){
                  
                    Parser.submit_command(OutputObj);
                      
                });
              
                $( '#output' ).on( 'click', 'a', {parserObj:Parser, characterItem:CharacterObj}, function(event){
                  
                    var elem = event.target;
                    switch(elem.getAttribute('type'))
                    {
                      
                        case 'goto':
                           // alert(event.data.characterItem.return_name());
                            //Traveler.travel(elem.getAttribute('name'), elem.getAttribute('area'), elem.getAttribute('region'), Parser);
                        break;
                      
                    }
                  
                });
    
      
    });
    Code (markup):
    The following code is in character.js

    as a note if I alert this.name from the .done it has a value, but that function this.return_name() never wants to call. When I can call it from another location it's undefined.

    function Character()
    {
          
        var name;  
          
        this.set_name = function()
        {
          
            $.ajax({
                      method: "POST",
                      url: "php/game/misc/get_character_name.php",
    
                    }).done(function( data ) {
                      
                            if(data != '')
                            {                          
                              
                                this.name = data;
                                this.return_name();
                              
                            }
                      
                      });
          
          
    
          
        }
      
        this.return_name = function()
        {
          
            alert('In Return Name');
          
          
        }
      
    }
    Code (markup):
    this.return_name() never fires..

    The main problem that got me hunting through this bug is the commented out code from the window.

    $( '#output' ).on( 'click', 'a', {parserObj:Parser, characterItem:CharacterObj}, function(event){
                  
                    var elem = event.target;
                    switch(elem.getAttribute('type'))
                    {
                      
                        case 'goto':
                           // alert(event.data.characterItem.return_name());
                            //Traveler.travel(elem.getAttribute('name'), elem.getAttribute('area'), elem.getAttribute('region'), Parser);
                        break;
                      
                    }
                  
                });
    Code (markup):
    links are added dynamically from other scripts. When the link is clicked travel is called with arguments, to update character location in DB. This doesn't work either.

    function CharacterTraveler()
    {
      
        this.travel = function(nameSet, areaSet, regionSet, ParserObj)
        {
          
          
          
            $.ajax({
                      method: "POST",
                      url: "php/game/set_character_location.php",
                      context:this,
                      data: { nameObj: nameSet, areaObj: areaSet, regionObj: regionSet, characterNameObj:characterName }
                    })
                      .done(function( data ) {
                      
                            if(data != '')
                            {
                                                          
                                alert(data);
                              
                            }
                      
                      });
          
        }
    
    }
    Code (markup):
    Any idea. Is it still my misunderstandings of Async and callbacks? Or something else?
     
    Jeremy Benson, Apr 3, 2017 IP
  2. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #2
    You're missing that the scope of 'this' changes inside a AJAX callback.... it's one of the things jQuery can't normalize either. Simply put, inside the scope of that callback "this" is referring to that anonymous function, not the parent object... as such when you assign "this.data=" you're assigning it to the anonymous function, not 'CharacterTraveler', when you try to call this.return_name you're trying to call a method that doesn't even EXIST on the callback function, and not 'CharacterTraveler.return_name'.

    Also welcome to another reason you couldn't pay me to use the pile of shit that is jQuery.

    Generally speaking, objects and AJAX are one of the biggest pains in the ass you can come across. jQuery only makes this WORSE with how it wraps AJAX with an abstraction that removes a LOT of the control from it -- like passing you just the data instead of the actual XMLHttpRequest object or a normalized version of the IE ActiveX equivalent. It's a stunning example of 'false simplicity' in that by dumbing it down like they have, they've made it harder to do certain things with it.

    If you were using vanilla JavaScript or something like my elementals library, I'd tell you to pass 'this' on the XMLHttpRequest object by reference, since that would get passed to the handler as a parameter instead of the uselessly neutered 'data' parameter.
     
    deathshadow, Apr 26, 2017 IP