Help needed on Twitch TV app "TypeError: Cannot read property 'stream_type' of null"

Help needed on Twitch TV app "TypeError: Cannot read property 'stream_type' of null"
0

#1

Creating an end point URL

`https://api.twitch.tv/kraken/channels/${streams[i]}?client_id=${clientId}`

Does not provide the status of whether the stream is live. In order to check the status of the stream I have created a function called checkStatus(stream) which receives the argument streams[i] from the array of twitch user names specified by fCC.

The problem I am having is that the function returns “undefined” and the console message reads “uncaught (in promise) TypeError: Cannot read property ‘stream_type’ of null”

Here is my function code:

function checkStatus(stream) {

      const streamEndpoint = `https://api.twitch.tv/kraken/streams/${stream}?client_id=${clientId}`;  
   
    fetch(streamEndpoint)
    //specifies we are expecting a JSON response
        .then(response => response.json())

        // handle the JSON data 
        .then(data2 => {
            const status = data2;
//       console.log(status.stream);
        if (status.stream.stream_type){
            return "IS CURRENTLY LIVE!";
        } else {
            console.log(status.stream.stream_type);
            return "OFFLINE"
        }
        

       
        
    });
              

}

I would be very grateful for any insight into how to fix this.


#2

How about checking for status.stream first, then check for status.stream.stream_type if stream is not null?


#3

Still returns “undefined”…


#4

In what context are you calling the checkStatus function? Even if you did the following:

function checkStatus(stream) {
  const streamEndpoint = `https://wind-bow.glitch.me/twitch-api/streams/${stream}`;

  fetch(streamEndpoint)
    //specifies we are expecting a JSON response
    .then(response => response.json())
    // handle the JSON data
    .then(data2 => {
      const status = data2;
      if (status.stream) {
        console.log('live')
        return "IS CURRENTLY LIVE!";
      } else {
        console.log('not on')
        return "OFFLINE";
      }
    });
}
var result = checkStatus("FreeCodeCamp");
console.log(result);

result will still be undefined, because fetch is asynchronous and when the function checkStatus is first called, it does not wait until the data comes back before the console.log executes.

Since fetch returns a Promise, you could do the following:

function checkStatus(stream) {
  const streamEndpoint = `https://wind-bow.glitch.me/twitch-api/streams/${stream}`;
  const status =  fetch(streamEndpoint)
    .then(response => response.json())
    .then(data2 => data2.stream ? "IS CURRENTLY LIVE!" : "OFFLINE");
  return status;
}
checkStatus("FreeCodeCamp").then(res=> console.log(res));

I am fairly new to using Promises and someone with more knowledge could probably rewrite my code to make it better.


#5

The console.log(status.stream) returns either a NULL or an object but for some reason when running IF…ELSE statement to return the string “ONLINE” or “OFFLINE” it is passed as undefined in the HTML of the display node.

Your code just returns the promise object, rather than “undefined” status I now have “[object Promise]”. Thanks anyways but its back to the drawing board.


#6

I have figured out what the problem is. I cannot reference a JSON call from an external function. The function makes an asynchronous call, so the data won’t be available when accessing the DOM updates from the first call.

Rather than calling he fetch and promise from a function I nested it inside the first fetch and promise and moved the DOM updates inside the second one. Here is the code:

 // loop through streams
    for (let i = 0; i < streams.length; i++) {
        
    //  sets the endpoint  
        const channelEndpoint = `https://api.twitch.tv/kraken/channels/${streams[i]}?client_id=${clientId}`;
        const streamEndpoint = `https://api.twitch.tv/kraken/streams/${streams[i]}?client_id=${clientId}`; 
        

        //make AJAX request to Twitch TV
        fetch(channelEndpoint)
        //specifies we are expecting a JSON response
        .then(response => response.json())

        // handle the JSON data 
        .then(data => {
            
            fetch(streamEndpoint)
            .then(response => response.json())
            .then(data2 => {
                
                const results = data;
                const stream = data2;
                
               const status = stream.stream ? 'Online' : 'Offline';
                
               
            
            
            const logPic = document.createElement('img');
            
           
            
            //check to see whether a profile banner exist, if not then use a generic image
            if(results.profile_banner === null){
                logPic.src = "https://7oktng-bn1305.files.1drv.com/y4mU9tPVQCuFBXt5sjRBsmvjxi2f_vXYle9YLtLb69Wqr_z633tw6DxSnovrMxqddOOtdk2YKL916Ura8DSyZvjAY2dKPvrkboK5HMpt6T69hadwwhdJgkax-Cv5UFmN271qwHN8tBvlhtc4ptTTcGmO9rBqsqb3hZPKPRGnWAMyr6ADjXFHph-xDXkkJMOAFHM6akLJuOFv7ekxPGwGCbUsw?width=500&height=500&cropmode=none";
                
            } else { //set the object's profile banner as the logo picture
                 logPic.src = results.profile_banner;
            }
            // create a row node for the info
            const newNode = document.createElement('row');
            // assign Bootstrap columns and template literals to newNode
            newNode.innerHTML = `<div class = 'row'> <div class='col-md-3'><img src=${logPic.src}></div><div class='col-md-3'>${results.name}</div><div class='col-md-3'>${results.game}</div><div class='col-md-3'>${status}</div></div>`;
            // assign the parent node
            const parentDiv = document.getElementById("followerInfo");
            // child element does not exist
            const sp2 = undefined;
            // insert the info into the followerInfo div
            parentDiv.insertBefore(newNode, sp2); 
            })
            
//            console.log(checkStatus(streams[i]));
            
            });
    }

Thank you @joesmith100 for your useful answer in another forum topic regarding this project.