title: Uncaught TypeError: Cannot read property 'then' of undefined when chaining 3 getJson calls
body: <p>I'm new to chaining JavaScript promises. I read all of the answers regarding above error. Added lots of return, but still, do not understand why it is returning undefined. </p>
  
  <p>I have 3 getJson calls (user, logo and stream). Data from all three are colected in thisNameInfo array and used to build html.</p>
  
  <p>In one of the prevous versions all then statments were chained in one signle line. That did not produce error, but the html was build before the getJson call was executed. After reading this thread <a href="https://stackoverflow.com/questions/37177725/how-to-chain-then-functions-and-callback-success-function-in-angular-js">how to chain then functions</a> I added 3 call routines (callUser, callLogo and callStream). </p>
  
  <p>It passes first callUser and gives me <em>Cannot read property 'then' of undefined</em> for 'then' after the callLogo. Point of error is underline in the code with ``````````````.</p>
  
  <p>Thanks for help. </p>
  
  <p>If you have suggestiong how to better pass data from getJson calls to function that build html I would love to hear it.</p>
  
  <p>Here is my code:</p>
  
  <pre><code>var allStreamers = ["freecodecamp", "animeexpo", "brunofin"];
  
  // build html for one stereamer
  var buildStreamerHtml = function(thisNameInfo){
    //build html using thisNameInfo
    ... some code goes here
    $("#display").append(html);
  };
  
  // get user 
  var user = function(name, thisNameInfo){  
    // return promise or "then" will return undefined!!!
    return $.getJSON(
        "https://wind-bow.glitch.me/twitch-api/users/" + name,
        function(data) {
          // if user does not exist data.error if 404 and data.message exist
          if (data.message) {
            thisNameInfo.userExist = "no";
            thisNameInfo.title = data.message;
            thisNameInfo.url = "#";
            thisNameInfo.logo = "";
          } else{
            thisNameInfo.userExist = "yes";
          }
        });     
  };
  
  // get logo, title and url
  var logo = function(name, thisNameInfo){
    if (thisNameInfo.userExist === "yes"){
      // get logo and title with link to url    
      // return promise or "then" will return undefined!!!
      return $.getJSON("https://wind-bow.glitch.me/twitch-api/channels/" + name,    
              function(dataChannel) {
                thisNameInfo.url = dataChannel.url;
                thisNameInfo.title = dataChannel.display_name;
                thisNameLogo.logo = dataChannel.logo;
              });  
    } 
  };
  
  // get stream title and number of watchers
  var stream = function(name, thisNameInfo){
    if (thisNameInfo.userExist === "yes"){
      // return promise or "then" will return undefined!!!
      return $.getJSON("https://wind-bow.glitch.me/twitch-api/streams/" + name,
              function(dataStreams) {
                if (dataStreams.stream) {
                  thisNameLogo.status =   "Online";
                  thisNameLogo.streamTitle =  dataStreams.stream.channel.status;
                  thisNameLogo.viewers =  dataStreams.stream.viewers;
                } else {
                  thisNameLogo.status =   "Offline";
                }
              });  
    }
  };  
  
  var callUser = function(name, thisNameInfo){
    return user(name, thisNameInfo).then(callLogo(name, thisNameInfo));
  };
  
  var callLogo = function(name, thisNameInfo){
    return logo(name, thisNameInfo).then(callStream(name, thisNameInfo));
  };                                ``````````````````````````````````````
  
  var callStream = function(name, thisNameInfo){
    return stream(name, thisNameInfo);
  };
  
  // link together all asinhronious calls for one streamer
  var getStreamerInfo = function(name){
    "use strict";
    // this variable builds up by assinhronious calls 
    // then its value is usedd by buildStreamerHtml
    console.log("getStreamerInfo name: " + name);
    var thisNameInfo = {}; 
    callUser(name, thisNameInfo).then(buildStreamerHtml(thisNameInfo));
  };
  
  // loop through all streamers and display them
  allStreamers.forEach(getStreamerInfo); 
  </code></pre>
  
  <p>The undefine points after the second promise callLogo</p>