4

I'm looking to chain multiple ajax requests, something along the lines of: get first JSON, if successful move on and get second JSON, if successful make a new object consisting of both JSON data.

// get first json
$.getJSON('http://www.json1.com').then(function(json1){
    return json1
}).then(function(json1){
    // get second json
    $.getJSON('http://www.json2.com').then(function(json2){
        var both = {}
        both.one = json1
        both.two = json2
        return both
    })
})

Should I be nesting .then statements in each other? I'm not completely sure how to get the both variable.

cat-t
  • 1,346
  • 1
  • 18
  • 34
  • is it not working? Also, you're using `.then()`, but this doesn't really differ from just using the callback argument. why not just use that instead? – kennypu May 15 '14 at 00:19
  • Hmm, I might not understand the concept correctly. I think I should also be incorporating the `Promise` part as well. – cat-t May 15 '14 at 00:30
  • well in the case like yours, there's no problem doing `$.getJSON('url', function(json1) { $.getJSON('url2', function(json2) { /* work with json1 and json2 */ })});` you would usually use promises when you want to wait for both: `var p1 = $.getJSON('url1'); var p2 = $.getJSON('url2'); $.when(p1,p2).then(function(json1,json2) { /* do something */});` – kennypu May 15 '14 at 00:33

2 Answers2

4
.then(function(json1){
    return json1
})

That's an unnecessary, (nearly) identity call.

.then(function(json1){
     …;

You should always return from a then callback, so that the new promise gets a value. You can even return promises, which will be "unwrapped"!

Should I be nesting .then statements in each other?

It doesn't really matter whether you nest them or chain them, that's the great thing about promises. Chaining them reduces the height of your "pyramid", so it is considered cleaner, however you cannot access the variables from higher scopes. In your case, you need to access json1, so you have to nest them.

I'm not completely sure how to get the both variable.

When you do return from the callbacks, you can get it as the resolution value of the promise that you get back from the then call.

$.getJSON('http://www.json1.com').then(function(json1){
    return $.getJSON('http://www.json2.com').then(function(json2){
        return {one: json1, two: json2};
    })
}).then(function(both) {
    // do something with both!
});
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Bergi, you're answer assumes he doesn't want access to `both` outside of the function, which he probably shouldn't, but might. – dgo May 15 '14 at 00:53
  • Just what I was looking for. Your explanation also cleared up a few things for me, thanks! – cat-t May 15 '14 at 00:59
  • Yes he can. My answer allows for that possibility. – dgo May 15 '14 at 02:58
  • @Bergi - And barring some compelling evidence to the contrary, I still think my answer is cleaner and more flexible - as long as both is scoped to avoid Mem leaks. – dgo May 15 '14 at 03:05
  • @user1167442: No, "outside of the callback" implies "is not yet loaded". – Bergi May 15 '14 at 04:04
  • Yeah that's valid. What mine allows for - and I was probably tunnel visioned when I wrote it because of what I was working on - is preloading a whole bunch of data and manipulating it before using it at a later time to reduce simultaneous processing load. – dgo Jun 06 '14 at 20:54
-3

I am editing this. I misstated what the problem is. The problem is that both is defined inside of a function and it is not accessible outside of the function unless you define both as an Object outside of the function. As you have it created, both is invisible to the entire world, and the only access to both as you have it created is handle it with another deferred callback, but still you don't have a variable defined to hold that Object and more to the point doing it that way would be retarded.

Here is a clean and simple way to accomplish what you want.

 var json1=$.getJSON('http://www.json1.com');
 var json2=$.getJSON('http://www.json2.com');
 var both={};

 json1.then(json2).then(function(){
   both.one=json1.responseJSON;
   both.two=json2.responseJSON;
});

If you want to be cooler, wrap it in a function and pass the url as an argument. Just make sure to declare the both object in a scope where you can access it.

dgo
  • 3,877
  • 5
  • 34
  • 47