Search code examples
javascriptnode.jsecmascript-6

Properly getting the value of a JSON field from a JavaScript Promise object


I'm making a call to a url and trying to get the data as JSON, which I've basically copied from other answers on StackOverflow. However, responseData.title has two different values in the two calls I make in the second .then() call below:

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
}

In the first call, console.log(responseData.title), the log shows the title field from the json response.

In the second call, response = responseData.title (which is later returned in the method) assigns [object Promise] to response which I assume is a Promise's toString()

I'm not even going to pretend JavaScript is my forte, so if I'm missing something trivial, sorry in advance.

Edit: By "second call" I mean the second time I access. If you looked at the code now, what I mean is that when I return response, which I would have assumed would be assigned responseData.title, it is instead assigned [object Promise]

Edit2: Also I realize that '(null)' will never be passed on, regardless of what happens. It's just a leftover from one of the many times I've tried to make this work.

Edit3: I added the entire body of the method


Solution

  • What you did should work, So it's probably how you "call it a second time" that is causing a problem. Please explain what you are actually doing.

    In the mean time this could help

    Try doing this

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

    or this

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

    or as a function (why not?)

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

    Edit: Looking at your code, I'm guessing your are just calling your getTitleForId function plainly without any await or promise handling. An async function will always return a promise; here what you get when you call that function is a object of type Promise(string).

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