Estoy creando una extensión de Chrome en la que llamo a la API de YouTube y uso fetch() para hacerlo. No entiendo por qué obtengo una variable indefinida cuando llamo a la función. Aquí es donde estoy llamando a la función;
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; })y esta es la función misma;
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; }); }) }Soy bastante nuevo en las extensiones de JavaScript y Chrome, así que perdónenme si esto es algo obvio.
El problema aquí es que no devuelve nada de la función addToQueue . Esto siempre devolverá undefined . La declaración de devolución que está utilizando regresa de la devolución de llamada, pero no de la función en sí.
Actualice su método y coloque un retorno delante de la llamada de búsqueda, así:
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() }) }Al llamar a este método async/await, deberá actualizar su función de escucha de eventos para que sea asíncrona.
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; })Además, he usado la nueva sintaxis async/await después de discutir con OP en los comentarios