1

I am writing a Javascript SDK to interact with a web service. I am using jQuery to do my AJAX calls.

When an AJAX call fails, I have registered an event handler for the ajaxError that gets called at the top of my .js file. My problem, and I don't understand why, is that when it gets called I have no way of accessing class member variables for my Akamanda.Client.

I tried adding another method for Akamanda.Client as .prototype.logError, which got called by the jQuery Ajax handler, but even then a test for (this.logging) failed as well.

How can I access class member variables from jQuery callbacks? What am I failing to understand here? Akamanda.Client.logging is undefined from the ajaxError callback.

My code for the SDK:

$(document).ajaxError(function(event, jqxhr, settings, exception) {
    // more robust error handling for different conditions
    if (Akamanda.Client.logging) {
        console.log('FAILED: ' + settings.type + ' ' + settings.url + ' => ' + exception);
    }
});

Akamanda.Client = function(options) {

    this.URL = options.URL || 'http://m-test.akamanda.com';
    this.baseURL = this.URL + '/api/' + Akamanda.API_VERSION;
    this.feedsURI = '/websyndication/feed/';

    // who is the client? (iphone/android/web)
    this.clientName = options.clientName;

    // For development: Logging and buildcurl IS ON, for production: OFF
    //this.logging = options.logging || true;
    this.logging = true;

    // called when a user is not authorised (Disabled)
    // this.logoutCallback = options.logoutCallback || null;
}

Akamanda.Client.prototype.getFeeds = function(callback){
    var feeds = [];
    $.getJSON(this.baseURL + this.feedsURI, function(data) {
        $.each(data, function(index, feed) {
            feeds[index] = {
                name: feed.name,
                title: feed.title,
                link: feed.link
            };

        })
        callback(feeds);
    });//.error(function(err) { (disabled at the moment in favour of ajaxError event)
       //     console.log('Error: ' + err.error);
       // });    
}

My code for the client (in another JS source file):

var options = { logging: true };
myAPI = new Akamanda.Client(options);
var feeds = [];
var articles = [];

function getFeeds()
{
    myAPI.getFeeds(function(AkamandaFeeds) {
        feeds = AkamandaFeeds;
        showFeeds();
    });
}

1 Answer 1

0

As far as I can see from the code you posted, you are never instantiating an object of type Akamanda.Client.

var Client = new Akamanda.Client();

or

var Akamanda.Client = {};

Akamanda.Client.logging = ....

JSBin Example: http://jsbin.com/ajidig/1/edit

Ok, here a little example(real code but very simplified):

//we wrap our code in a self invoking function so that we don't pollute the global    namespace, see http://stackoverflow.com/questions/6715805/self-invoking-functions-javascript for further details
(function(){
     //create your object that holds all your function, that are different ways to do this
     var Akamanda = {};

     //a private function 
     function ErrorHandler(clientObj) {
          this.clientObj = clientObj;
          //do whatever with clientObj
          this.log = function(){..}
     } 
      //private constructor for clientobj
     function Client(options){
         ..
     }



     Akamanda.Client = function(){

       var newClient = new Client({..});
       //setup
       Akamanda.ErrorLogging = new ErrorHandler(newClient);
       return newClient;
     }

     //bind our service to the window object to make it accesible

     window.Akamanda = Akamanda;
})()


//client

var myAPI = Akamanda.Client();
Akamanda.ErrorLogging.log();

I hope this basic examples helps. If you need to know more about Javascript Patterns, I can recommend this book http://jsninja.com/ by John Resig, the creator of jQuery. Depending on what you want to do, there's also a lot of frameworks like http://backbonejs.org/ that help with this kind of stuff.

Sign up to request clarification or add additional context in comments.

8 Comments

I have updated my original question to include the consumer's source as well.
Basically the same problem. if (Akamanda.Client.logging) is a static call. If I understand your example correctly, you want if(myAPI.logging) in the ajaxerror callback.
But how would I know what a consumer (i.e. who ever utilises this SDK to access the web services) chooses to call their instantiated API object?
Well that is an entirely different problem. Instead of a constructor you could provide a factory method that returns a client service. This method also registers the new client service with some kind of debugging/ error handling entity that chooses which client obj is being used in the callback. But as I said, this is more a design question and has not much to do with your original question.
I would consider that a valid answer since the answer to my question is "impossible in this context."
|

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.