0

I am trying to store the actual response from a Promise to a variable

let token;
let tokenPromise = new Promise(function(resolve, reject) {
    fetch(tokenUrl, options)
        .then(res => {
            if (res.ok) {
                return res.json()
            } else {
                reject('Not clean')
            }
        }).then((data) => {
            resolve(data.access_token)
        })
})
token = tokenPromise.then(res => {return res})
return token

When this is run, token returns as the Promise object and not the actual response. How do I store the actual response or a value from the response as a variable within the parent function?

user3261712
  • 9
  • 1
  • 2

4 Answers4

0

I'd create a method called get token first.

Updated/simplified based off 4castle's suggestion

getToken() {
    return fetch(tokenUrl, options)
            .then(res => res.json())
            .then(data => data.access_token)
}

Then inside the method you'd like to use the token

someMethod() {
    getToken().then(token => {
        // Use it.
    })
}
Proximo
  • 6,235
  • 11
  • 49
  • 67
  • 1
    `tokenPromise` isn't a function, so there shouldn't be parentheses after it in the `await`. Also, it would be good to fix their use of the [promise construction antipattern](https://stackoverflow.com/q/23803743/5743988). – 4castle Mar 10 '18 at 23:20
  • Yeah I've revised my answer. I think he's wanting to make async calls in a sync method which isn't possible so here's what I'd recommend instead. – Proximo Mar 10 '18 at 23:24
  • Looks good, now just remove the `new Promise` wrapper, since `then` already returns a promise that you can return. – 4castle Mar 10 '18 at 23:26
  • Nah you need that to actually return a promise in order to use then. – Proximo Mar 10 '18 at 23:27
  • `fetch` returns a promise, which is chained using `then`, so there's no need to use the promise constructor. See the post I linked to for more info – 4castle Mar 10 '18 at 23:29
  • Yeah that's true but do you really want to write fetch every time you need a token? I'd still use a promise method here. – Proximo Mar 10 '18 at 23:31
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/166605/discussion-between-proximo-and-4castle). – Proximo Mar 10 '18 at 23:32
  • I'm saying to use `getToken() { return fetch(...).then(...).then(...); }` – 4castle Mar 10 '18 at 23:32
  • Just testing it out, you're right. Hmm, okay I'll update.. thank you. – Proximo Mar 10 '18 at 23:43
0

Because the function then returns a promise.

An alternative is to use an async function.

function getToken() {
  let tokenPromise = new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve('myNewToken');
    }, 100);
  });

  return tokenPromise;
}

async function main() {
  let token = await getToken();
  console.log(token);
}

main();
Ele
  • 33,468
  • 7
  • 37
  • 75
  • Yeah I like this. There's no way to get the return of async calls inside a sync method that I know of, which I think he's asking. – Proximo Mar 10 '18 at 23:15
0

Why you create a new Promise around fetch?

function status(res) {
  if (res.ok) {
    return Promise.resolve(res)
  } else {
    return Promise.reject(new Error(res.statusText))
  }
}

function json(res) {
  return res.json()
}

function getToken() {
  return fetch(tokenUrl, options) // Fetch URL
    .then(status) // Is everything nice?
    .then(json) // Response to json
    .then(jsonData => jsonData.access_token) // return access_token
    .catch(function(error) { // Some S*ht Happens :(
      console.log('Request failed', error);
      /* ErrorHandling Stuff */
    });
}
fehrmann
  • 69
  • 3
0

You could use ES7 async/await

let token;
let tokenPromise = async () => {
  try {
    const res = await fetch(tokenUrl, options);
    const data = await res.json();
    return data.access_token
  } catch (error) {
    console.error('Error fetching token', error);
    return 'Not clean';
  }
}
token = tokenPromise().then(res => res);
return token;
Sam Logan
  • 3,343
  • 2
  • 17
  • 13