chris
chris

Reputation: 36937

javascript jquery function is this somehow wrong?

function rebuildJSONObject(){
   $.getJSON('services.json', function(data) {
        //stof start
        var input = data;
        var output = { myservices: [] };
        for (var key in input) {
            if (input.hasOwnProperty(key)) {
                for (var i = 0, hostsinfo = input[key].hostsinfo; i < hostsinfo.length; i++) {
                    output.myservices.push({
                        'nametag': key,
                        'hostidn': hostsinfo[i]['hostidn'],
                        'details': hostsinfo[i]['details'],
                        'currstatus': hostsinfo[i]['currstatus'],
                        'currstatusclass': hostsinfo[i]['currstatusclass']
                    });
                }
            }
        }
        //stof end
        return output;
    });
}
//setting it for use later in the script
var serviceJSONObject = rebuildJSONObject();

I know the stuff going on in the function is working properly cause if I apply it to a click event it works charming. However I would rather load the JSON object into memory once and work with it client side there after unless saved. My Problem is however anywhere I call serviceJSONObject I get an "undefined" error.

So How am I doing this wrong and how would I define a variable like this early in the game so the rest of the script can use said variable.

Upvotes: 2

Views: 65

Answers (3)

Lapple
Lapple

Reputation: 3373

Why not add a cache property to a function that will store the result of the initial output (loaded via ajax) and returning the saved state to any consecutive call.

function rebuildJSONObject(callback) {
    var self = this;

    if (typeof self.cache !== 'undefined') {
        if (typeof callback === 'function') {
            callback(self.cache);
        }
        return;
    }

    $.getJSON('services.json', function(data) {
        //stof start
        var input = data,
            output = { myservices: [] };

        for (var key in input) {
            if (input.hasOwnProperty(key)) {
                for (var i = 0, hostsinfo = input[key].hostsinfo; i < hostsinfo.length; i++) {
                    output.myservices.push({
                        'nametag': key,
                        'hostidn': hostsinfo[i]['hostidn'],
                        'details': hostsinfo[i]['details'],
                        'currstatus': hostsinfo[i]['currstatus'],
                        'currstatusclass': hostsinfo[i]['currstatusclass']
                    });
                }
            }
        }
        //stof end
        self.cache = output;

        if (typeof callback === 'function') {
            callback(self.cache);
        }

        return;
    });
}

EDIT: For the first time you will need to call this function asynchronously and supply a callback function, for example

rebuildJSONObject(function(output) {

    /*
     * Process your output here
     */

    console.log(output);

});

Each consecutive time you can again use it synchronously:

console.log(rebuildJSONObject.cache);

Upvotes: 0

njr101
njr101

Reputation: 9619

There are a couple of problems with this.

  1. The call to getJSON is asynchronous so you need to be careful you don't try to use the results before the call has returned your results.

  2. The way it is at the moment, the results will not be returned to serviceJSONObject. The return output statement is setting the return for the anonymous function, not the return value for rebuildJSONObject, so the results will just disappear. If you want the results to be available elsewhwere in code you will either need to store them in a global variable or access them inside the callback.

Upvotes: 0

detaylor
detaylor

Reputation: 7280

The issue is that output is returned before the callback function is called. You should be able to save the value to serviceJSONObject by using a closure:

function rebuildJSONObject(serviceJSONObject){
   $.getJSON('services.json', function(data) {
        //stof start
        var input = data;

        // Use the serviceJSONObject that is passed into rebuildJSONObject
        serviceJSONObject = { myservices: [] };
        for (var key in input) {
            if (input.hasOwnProperty(key)) {
                for (var i = 0, hostsinfo = input[key].hostsinfo; i < hostsinfo.length; i++) {
                    serviceJSONObject.myservices.push({
                        'nametag': key,
                        'hostidn': hostsinfo[i]['hostidn'],
                        'details': hostsinfo[i]['details'],
                        'currstatus': hostsinfo[i]['currstatus'],
                        'currstatusclass': hostsinfo[i]['currstatusclass']
                    });
                }
            }
        }
        //stof end
    });
}
//setting it for use later in the script
var serviceJSONObject;
rebuildJSONObject(serviceJSONObject);

Upvotes: 1

Related Questions