-4

I am working with an API and mananged to get the .ajax function working just fine. Now, I need to use the information from the API outside of the .ajax function. To do that, I am trying to use jQuery's .done function, but it's not working. I looked at a few solutions to similar problems and I have had no luck. I tried it with and without the $.when function, but neither works.

//create user prototype
function user(name,logo,status,streamLink,streamViews,streamGame){
  this.name = name;
  this.logo = logo;
  this.status = status;
  this.streamLink = streamLink;
  this.streamViews = streamViews;
  this.streamGame = streamGame;
  this.getUserInfo = function(userName) {
    return $.ajax({
      dataType: "jsonp",
      data:{},
      url:'https://api.twitch.tv/kraken/users/'+userName+'?callback=?',
      success:function(data){
        this.name = data.display_name;
        this.logo = data.logo;
        this.bio = data.bio;
        $('.test').html(this.logo);
      }     
       
    }) 
  }
}

//create user for each stream
var freeCodeCamp = new user('freeCodeCamp');
var medrybw = new user('medrybw');
//call getUserInfo function
freeCodeCamp.getUserInfo('freeCodeCamp');
medrybw.getUserInfo('medrybw');


//display medrybw status (test) - not working! 
when(medrybw.getUserInfo()).done(function(data){
  alert('test');
  $('.test2').html(medrybw.bio);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test"></div>
<br>
<br>
<div class="test2"></div>

The part that is not working is that last function. If I remove the $.when part, I get the "test" alert working fine, but not the other line. With the $.when, neither line runs. I am really confused.

isherwood
  • 58,414
  • 16
  • 114
  • 157
Marie Pelletier
  • 417
  • 2
  • 4
  • 15
  • 1
    You don't have `$.when`. You just have `when`. – isherwood Sep 14 '15 at 18:44
  • You only need to use `$.when` if you are working with **multiple** promises. `$.when(x)` is the same as `x`. The problem is rather that `this` inside your success callback does not point to the object (that and the fact that `when` (what you use) does not exist). See http://stackoverflow.com/q/20279484/218196 – Felix Kling Sep 14 '15 at 18:45
  • `this` isn't what you think it is, inside of ajax success. – Kevin B Sep 14 '15 at 18:49

2 Answers2

1

If you are working with a single promise, there is no need to use $.when. Just do

medrybw.getUserInfo().done(...);

(In fact, if you pass a single promise to $.when, it will return it, i.e. $.when(x) === x).

If I remove the $.when part, I get the "test" alert working fine, but not the other line.

The line itself "works" fine, the issue is that medrybw.bio does not exist.

this inside the success callback does not point to the object, so the bio property is never set on medrybw. See How to access the correct `this` context inside a callback? for a solution to that problem.


I highly recommend to make yourself familiar with your browser's developer tools so that you can set breakpoints and inspect variables, to better analyze your code and know what does and does not work (instead of jumping to conclusions).

Community
  • 1
  • 1
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Thanks everyone for taking the time to help a newbie :-) I got it to work using the .bind(this) but will keep reading up to make sure I understand how 'this' works because it is clearly more complicated than I thought. – Marie Pelletier Sep 14 '15 at 19:17
0

You don't need the $.when() part. The trouble you are having is that this refers to the jqXHR object, and not the user object, in the success function of your ajax call. To resolve, use .bind(this).

Second, getUserInfo() expects a userName argument, but when you call it later you omit that argument. Also, calling getUserInfo() multiple times results in redundant and unnecessary ajax requests. The first time you call the function, you can replace it with a function that just returns the original jqXHR object and avoid redundant ajax calls, while also removing the requirement for the userName argument in subsequent calls.

//create user prototype
function user(name,logo,status,streamLink,streamViews,streamGame){
  this.name = name;
  this.logo = logo;
  this.status = status;
  this.streamLink = streamLink;
  this.streamViews = streamViews;
  this.streamGame = streamGame;
  this.getUserInfo = function(userName) {
    var jqXHR = $.ajax({
      dataType: "jsonp",
      data:{},
      url:'https://api.twitch.tv/kraken/users/'+userName+'?callback=?',
      success:function(data){
        this.name = data.display_name;
        this.logo = data.logo;
        this.bio = data.bio;
        $('.test').html(this.logo);
      }.bind(this)     
       
    });
    this.getUserInfo = function(){return jqXHR;};
    return jqXHR;
  }
}

var medrybw = new user('medrybw');
medrybw.getUserInfo('medrybw');

//display medrybw status (test) - not working! 
medrybw.getUserInfo().done(function(data){
  console.log(data);
  $('.test2').html(medrybw.bio);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test"></div>
<br>
<br>
<div class="test2"></div>
gilly3
  • 87,962
  • 25
  • 144
  • 176