Estoy llamando a una url e intentando obtener los datos como JSON, que básicamente he copiado de otras respuestas en StackOverflow. Sin embargo, responseData.title tiene dos valores diferentes en las dos llamadas que hago en la segunda llamada .then() a continuación:

var getTitleForId = async function(id) {
    if (!id)
        return false

    let url = id + "other stuff to make a valid api call"

    let response = '(null)'

    await fetch(url)
        .then((resp) => resp.json())
        .then((responseData) => {
            console.log(responseData.title);
            response = responseData.title;
    })

    return response
}

En la primera llamada, console.log(responseData.title), el registro muestra el campo del título de la respuesta json.

En la segunda llamada, response = responseData.title (que luego se devuelve en el método) asigna [object Promise] a response, lo que supongo que es una Promesa toString()

Ni siquiera voy a fingir que JavaScript es mi fuerte, así que si me falta algo trivial, lo siento de antemano.

Editar: Por "segunda llamada" me refiero a la segunda vez que accedo. Si observa el código ahora, lo que quiero decir es que cuando devuelvo la respuesta, que suponía que se le asignaría responseData.title, en su lugar se le asigna [object Promise]

Edit2: También me doy cuenta de que '(nulo)' nunca se transmitirá, independientemente de lo que ocurra. Es solo un remanente de una de las muchas veces que he tratado de hacer que esto funcione.

Edit3: agregué todo el cuerpo del método

2
realmature 23 feb. 2018 a las 18:43

4 respuestas

La mejor respuesta

Lo que hiciste debería funcionar, así que probablemente sea cómo "lo llamas por segunda vez" lo que está causando un problema. Por favor explique lo que realmente está haciendo.

Mientras tanto, esto podría ayudar

Intenta hacer esto

var title = await fetch(url)
    .then(resp => resp.json())
    .then(responseData => responseData.title);

console.log(title);

O esto

var titlePromise = fetch(url)
    .then(resp => resp.json())
    .then(responseData => responseData.title);

titlePromise.then(console.log)

O como una función (¿por qué no?)

var getTitle = url => fetch(url)
    .then(resp => resp.json())
    .then(responseData => responseData.title);

getTitle(url).then(console.log)

Editar: Mirando su código, supongo que simplemente está llamando a su función getTitleForId sin ningún tipo de espera o manejo de promesas. Una función async siempre devolverá una promesa; aquí lo que obtienes cuando llamas a esa función es un objeto de tipo Promesa (cadena) .

https://www.twilio.com/blog/2015/10/asyncawait-the-hero-javascript-deserved.html

1
Overcl9ck 23 feb. 2018 a las 19:53

Está utilizando espera , por lo que en realidad no hay necesidad de molestarse con la confusa sintaxis y luego .

Su código podría reescribirse así:

const resp = await fetch(url);
const responseData = resp.json();
console.log(responseData.title);
const response = responseData.title;
console.log(response); // prints the title
0
Patrick Hund 23 feb. 2018 a las 16:10

Debe devolver su respuesta dentro de la primera then() llamada.

await fetch(url)
    .then((resp) => {
        return resp.json()
     })
    .then((responseData) => {
        console.log(responseData.title);
        response = responseData.title;
    })
0
Michael Czechowski 23 feb. 2018 a las 15:48

Creo que esto debería funcionar:

await fetch(url)
    .then((resp) => Promise.resolve(resp.json()))
    .then((responseData) => {
        console.log(responseData.title);
        response = responseData.title;
    })
0
John Detlefs 23 feb. 2018 a las 16:09