0

I'm making a chrome extension where I'm calling the youtube API and using fetch() to do so. I don't understand why I'm getting an undefined variable when I call the function. Here is where I'm calling the function;

document.querySelector("[type=button]").addEventListener("click", function() {
    //console.log("this was clicked");
    let videoId = document.getElementById('vidUrl').value;
    videoId = videoId.substring(videoId.indexOf('=') + 1);
    console.log(videoId);
    //chrome.runtime.sendMessage({ msg: "startFunc", vidId: videoId});
    let request = addToQueue(videoId);
    console.log(request);
    console.log(request.snippet.title);
    let table = document.querySelector(".table");
    let row = table.insertRow(table.rows.length);
    let title = row.insertCell(0);
    let author = row.insertCell(1);
    title.innerHTML = request.Data.snippet.title;
    author.innerHTML = request.Data.snippet.videoOwnerChannelTitle;
})

and this is the function itself;

function addToQueue(vidId){
    chrome.identity.getAuthToken({ interactive: true }, function (token) {
      //console.log(token);      
      let fetchString = 'https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&key=xxxxxxxxxxxxxxxxxx'
      let post = 
      {
        "part": [
          "snippet"
        ],
        "id": "UC0E5pDp_c2riLV4UhEgynKA",
          "snippet": {
            "playlistId": "PLu4fFFN_062GzqARIz3gnERiJ8M4GbRcL",
            "position": 1,
            "resourceId": {
              "kind": "youtube#video",
              "videoId": vidId
            }
        }
      }
      let fetchOptions = {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${token}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(post),
      }
      fetch(fetchString,fetchOptions)
        .then((response) => response.json())
        .then(function (data) {
          console.log(data);
          //console.log(typeof data);
          //chrome.runtime.sendMessage({Data : data});
          return data;
      });
    })
  }

I'm fairly new to javascript and chrome extensions so please forgive me if this is something obvious.

Peter
  • 15
  • 6
  • are you getting undefined in that console log? or from the output of running the method? – about14sheep May 08 '22 at 17:15
  • @about14sheep there is 2 console.logs I'm getting an undefined in the one where I'm calling the method and in the actual fetch method it's returning the JSON. It is also undefined from the output of running the method. – Peter May 08 '22 at 17:21

1 Answers1

0

The issue here is that you not returning anything from the addToQueue function. This will always return undefined. The return statement you are using returns from the callback, but not the function itself.

Update your method and put a return in front of the fetch call, like this:

async function addToQueue(vidId){
    return chrome.identity.getAuthToken({ interactive: true }, async function (token) {
      //console.log(token);      
      let fetchString = 'https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&key=xxxxxxxxxxxxxxxxxx'
      let post = 
      {
        "part": [
          "snippet"
        ],
        "id": "UC0E5pDp_c2riLV4UhEgynKA",
          "snippet": {
            "playlistId": "PLu4fFFN_062GzqARIz3gnERiJ8M4GbRcL",
            "position": 1,
            "resourceId": {
              "kind": "youtube#video",
              "videoId": vidId
            }
        }
      }
      let fetchOptions = {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${token}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(post),
      }
      const response = await fetch(fetchString,fetchOptions)
      return await response.json()
    })
  }

When calling this method the async/await you will need to update your event listener function to be async

document.querySelector("[type=button]").addEventListener("click", async function() {
    //console.log("this was clicked");
    let videoId = document.getElementById('vidUrl').value;
    videoId = videoId.substring(videoId.indexOf('=') + 1);
    console.log(videoId);
    //chrome.runtime.sendMessage({ msg: "startFunc", vidId: videoId});
    let request = await addToQueue(videoId);
    console.log(request);
    console.log(request.snippet.title);
    let table = document.querySelector(".table");
    let row = table.insertRow(table.rows.length);
    let title = row.insertCell(0);
    let author = row.insertCell(1);
    title.innerHTML = request.Data.snippet.title;
    author.innerHTML = request.Data.snippet.videoOwnerChannelTitle;
})

Also, I have used the new async/await syntax after discussing with OP in comments

about14sheep
  • 1,813
  • 1
  • 11
  • 18
  • still returns undefined :( – Peter May 08 '22 at 17:34
  • sorry just noticed all this is in the callback of `chrome.identity`, updated the answer to put a return there as well – about14sheep May 08 '22 at 17:37
  • still returning undefined, it was working when I sent it to the background script and then sent it back. – Peter May 08 '22 at 17:44
  • updated to add how to call the method in your event listener – about14sheep May 08 '22 at 17:50
  • Ok, I got it I had to replace the .then with "await" can you update your answer to reflect this so I can choose it as a solution? – Peter May 08 '22 at 18:21
  • I updated it, I have also added using async await inside the `addToQueue` function – about14sheep May 08 '22 at 18:24
  • wait never mind I just tested this with a call to the addToQueue function from the beginning of the script and this worked but when I call it from the other function it still doesn't work. – Peter May 08 '22 at 18:25
  • add async to the event listener function – about14sheep May 08 '22 at 18:26
  • I added async in front of my listener function like this ```document.querySelector("[type=button]").addEventListener("click", async function() {``` and it still returns undefined although it works when I run addToQueue in the beginning of the code. – Peter May 08 '22 at 18:41
  • have you tried reading through the question this one was mark a duplicate of? – about14sheep May 08 '22 at 18:43
  • Yea it's really complex I don't really understand it fully, I hate to be an asshole but I have this assignment due tomorrow and I don't think I have the time to understand this right now, I'll probably just stick with sending the data via sendMessage and I'll try and look into this later this week. – Peter May 08 '22 at 20:16