0

UPDATE: I decided that using the JS Module Pattern was not "keeping it simple", so I scrapped it and used jQuery's deferred object to return the data I was looking for. What I really needed was to simply load a JSON file and populate an object. I was just trying to be too fancy by incorporating the JS Module Pattern.

Many thanks to @kiramishima for the correct answer.

Below is the finished code:

function getData(){
    var url = CONTEXT + "/json/myJsonFile.json";
    return $.getJSON(url);
}

getData()
    .done(function(data){
        myGlobalObj = data;
    })
    .fail(function(data){
        console.log("fetching JSON file failed");
    });

I think I'm getting a little too fancy for my own good here. I'm loading a JSON file and trying to return the API via JS module pattern. Problem is that I believe I'm not implementing the promise correctly and I don't know how to fix it.

Here's my JSON:

{
    "result": {
        "one": {
            "first_key":"adda",
            "second_key":"beeb",
            "third_key":"cffc"
        },
        "two": {
            "first_key":"adda",
            "second_key":"beeb",
            "third_key":"cffc"
        }
    }
}

And here's my JS Module implementation:

var data = (function() {
    var url = "/json/dummy.json";
    var getAllData = function() {
        return $.getJSON(url, function(result){});
    };

    var promise = getAllData(); // the promise

    return {
        getFirstObjSecondKey:function() {
            return promise.success(function(data) {
                return data.result.one.second_key;
            });
        },
        getSecondObjThirdKey:function() {
            return promise.success(function(data) {
                return data.result.two.third_key;
            });
        },
    };
})();

The problem is that "getAllData()" is coming back as undefined and I'm not sure why; that method returns a Promise that I should be able to handle in the "done" function. How far off am I?

Thanks for any helpful input. This is the first time I'm messing with the JS Module Pattern.

fumeng
  • 1,771
  • 5
  • 22
  • 61
  • 3
    Doesn't matter how fancy you get, you still can't return data from an asynchronous ajax call. – adeneo Feb 16 '16 at 21:34
  • I imagine the simple solution would be to use the callback of $.getJson() to populate a global object; and the lesson learned would be to not get fancy trying to return an API that'll provide methods to extract precise elements out of the response. – fumeng Feb 16 '16 at 21:47

2 Answers2

1

I dont know what is your problem, but I test with:

var getAllData = function() {
return $.getJSON('/json/dummy.json', function(result){})
}

getAllData().done(function(data){ console.log(data.result.one.second_key) }) // prints beeb

works fine in that case, but if try this:

var data = (function() {
    var url = '/json/dummy.json';
    var getAllData = function() {
        return $.getJSON(url, function(result){});
    };

    return {
        getFirstObjSecondKey:function() {
            getAllData().done(function(data) {
                return data.login;
            });
        },
        getSecondObjThirdKey:function() {
            getAllData().done(function(data) {
                return data.name;
            });
        },
    };
})();

data.getFirstObjSecondKey returns undefined, then can u pass anonymous function:

var data = (function() {
        var url = '/json/dummy.json';
        var getAllData = function() {
            return $.getJSON(url, function(result){});
        };

        return {
            getFirstObjSecondKey:function(callback) {
                getAllData().done(function(data) {
                    callback(data.result.one.second_key);
                });
            },
            getSecondObjThirdKey:function(callback) {
                getAllData().done(function(data) {
                    callback(data.result.two.third_key);
                });
            },
        };
    })();
var t; 
data.getFirstObjSecondKey(function(data){ 
//data should contain the object fetched by getJSON
console.log(data);  // prints beeb
t = data; // assign t
})
console.log(t) // prints beeb

Other solution, return always the deferred object

Kiramishima
  • 192
  • 1
  • 7
  • After thinking that I found the answer I researched more and came to the conclusion that your answer was right on target! Thank you. – fumeng Feb 17 '16 at 02:28
1

kiramishima's answer works, but it mixes callbacks with Promises. If you're using promises, you should try not to mix both styles.

You have to return a Promise from your functions. Remember that promises can be chained, that is, if you return a Promise from the done function, that becomes the new Promise

var data = (function() {
    var url = "/json/dummy.json";
    var getAllData = function() {
        return $.getJSON(url, function(result){});
    };

    return {
        getFirstObjSecondKey:function() {
            return getAllData().done(function(data) {
                return new Promise(function(resolve, reject){
                  resolve(data.result.one.second_key); 
                });
            });
        },
        getSecondObjThirdKey:function() {
            return getAllData().done(function(data) {
                return new Promise(function(resolve, reject){
                  resolve(data.result.one.third_key);
                });
            });
        },
    };
})();

data.getFirstObjSecondKey().done(function(secondKey) {
    console.log('Second key', secondKey);
});
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
  • Good point about not mixing with callbacks, thank you. I like your method but I have decided, in the interest of keeping it simple, to forego using the JS Module Pattern. I have updated the code at the top of my initial question. – fumeng Feb 17 '16 at 13:20