Passing variables from Ajax success method to the then method


#1

Hi all,

Below is a small example of calling some JSON, displays a list via the Mustache template engine, everything's good.

The trouble is. I'd like to make another AJAX call and get some other JSON. But. I need the value from one of the variables inside the success method passed/available to the then method.

How do we get the snippet value from success?

var people = "https://swapi.co/api/people/";

$.getJSON(people, function(data) {
    var template = $('#results_tpl').html();
    var html = Mustache.render(template, data);
    $('#results').html(html);
  })
  .success(function() { 
    var snippet = "Hello Barry, working with JSON.";
    console.log(snippet);
  })
  .then(function() {
    console.log(snippet); //snippet is not defined

    //...get some other JSON based on the snippet value
  });

For reference if needed Codepen

Thanks, Barry


#2

You can return it from your success function and accept it as a parameter to your then function.

This is called promise chaining. See https://javascript.info/promise-chaining


#3

Thanks @rpkamp

I'll give this a read and see if I can get things to work.
Was just writing some test code using .bind from a callback, not sure if that would work :upside_down:

Post back shortly,
Barry


#4

Doing lots of reading :slight_smile:

I was going to start talking about the Fetch API @rpkamp and if this would be a better approach than AJAX, though after further reading, the support is not the best and introducing polyfills. Though looks exciting.

For another day I think :nerd:

Ok, still not 100% about the promises, I get the idea.
Not sure if I need to add a new Promise somewhere in my code below.

You can return it from your success function and accept it as a parameter to your then function.

Is this what you mean?

  .success(function() { 
    var snippet = "Hello Barry, working with JSON.";
    console.log(snippet);
    return snippet;
  })
  .then(function(snippet) {
    console.log(snippet);
  });

Now instead of

snippet is not defined

It returns the full people object, why is that and how do I just get the variable value?
Updated codepen

Thnaks, Barry


#5

Can anybody advise on the above?
Small example maybe.

Cheers, Barry


#6

The callback you pass to $.getJSON(), .then() and .success() are all called when the request completes, so you kinda have a triple redundancy here (BTW .success() is actually deprecated). For a promise chain you might use .then() only like so:

$.getJSON(url).then(function handleResponse () {
  var template = $('#results_tpl').html()
  var html = Mustache.render(template, data)

  $('#results').html(html)

  return 'Hello Barry, working with JSON.'
}).then(console.log) // logs "Hello Barry, working with JSON."

#7

Thanks @m3g4p0p

Been trying different combinations trying to get what I need. I spent a good 30 mins trying to understand why things weren't working using your example.

I then realized, the function parameter was not wrapped in the parenthesis :upside_down:

$.getJSON(url).then(function handleResponse () {
to
$.getJSON(url).then(function(handleResponse) {

Good news. I have a value returning with the updated code, thanks for the explanation :sunglasses:

Ok, so now instead of console.log
.then(console.log) // displays value

I need to add the value into a variable so I can run another getJSON based on that value.

Something like:

// tag being the value return from console.log above
.then(function() {
  var test = "//example.com/" + tag;
  $.getJSON(test, function(data) {})
});

Not sure how this should fit together, and how do I call the value?

Code for reference or updated Codepen

var people = "https://swapi.co/api/people/";

$.getJSON(people).then(function(data) {
  var template = $('#results_tpl').html()
  var html = Mustache.render(template, data)

  $('#results').html(html);
  var tag = $('#results li').attr('data-skin');
  return tag
}).then(console.log)

/*
.then(function() {
  var test = "//example.com/" + tag;
  $.getJSON(test, function(data) {}
});
*/

Barry


#8

Is this what you want?


#9

I just used this as an example to see if I can access the value. I didn't mean to imply I needed the full array, should of used a better example, sorry for the confusion.

Thanks anyhow, I'll surely be needing this approach moving forward :slight_smile:

The issue is, as mentioned above #7 the value is display in the console using:
.then(console.log)

I now need to access this value var tag to run another getJSON.
Again, explained in my last post :nerd:

Cheers, Barry


#10

.then(function(tag) {
  var test = "//example.com/" + tag;
  $.getJSON(test, function(data) {}
});

#11

I did try this :slight_smile:

Something's not right, can't put my finger on the brackets matching up?

Can you see the error

$.getJSON(people).then(function(data) {
  var template = $('#results_tpl').html()
  var html = Mustache.render(template, data)

  $('#results').html(html);
  var tag = $('#results li').attr('data-skin');
  return tag
}).then(function(tag) {
  var test = "//example.com/" + tag;
  $.getJSON(test, function(data) {}
});

Thanks, Barry


#12

getJSON is missing closing parenthesis

}).then(function(tag) {
  var test = "//example.com/" + tag;
  $.getJSON(test, function(data) {});
});

#13

Good catch! :smile:
This is now working ha - been at this for some time :sunglasses:

If I have any further questions once I put everything together, will post back.

Cheers @rpkamp, and thanks also @m3g4p0p

Barry


#14

Oops sorry, forgot the data parameter... handleResponse was actually supposed to be the function name. ^^

Just curious... if that data-skin attribute is coming from the template you rendered with the data, wouldn't that value be available in the data anyway? Seems like a bit of an unnecessary DOM query here...

@computerbarry you can see such errors in the browser console (usually cmd / ctrl + shift + j)... you might also consider using a text editor that has linting capabilities. E.g. I'm mostly using VSCode, which highlights such syntax errors right in the code. Might save you a lot of headache... ;-)


#15

Does that mean I've missed something by not naming the function? It still works without.

This is what I thought. But, when I try and pass that value to the next .then method the value is undefined, hence this thread in the first place :slight_smile:

As things stand, if I don't return tag then the value is undefined.
Unless I've missed something?

E.g. I'm mostly using VSCode, which highlights such syntax errors right in the code.

Yes I use sublime 2. Funny enough, this is not supplied I used to favor netbeans which has all this. I need a small upgrade I think :nerd:

Thanks,
Barry


#16

Anonymous functions are usually fine, I just wanted to make clear that this is the function to handle the response. :-) (It also helps with debugging as you'll get more telling stack traces.)

Yes, the value you return from a then function (unless it is itself a promise) will get wrapped in another promise that immediately resolves with that value; this allows chaining like in the above example.

Yeah, sublime text is pretty bare bones by itself... which is certainly not a bad thing, but you'd probably need an extension for that then. With a full-fledged IDE you'll of course have more features out of the box... and IMHO VSCode does a pretty good compromise in this respect, but that's a matter of personal preference and requirements really.


#17

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.