-4

I am trying to get an auth token from an API and then store that Auth token and use it in subsequent calls to the API.

This is the code to get the token

const getToken = async (): Promise<string | void> => {
    const response = await fetch('https://exampleapi.com/auth', {
        method: 'POST', 
        body: JSON.stringify(body),
        headers: headers,
        agent: httpsAgent
    })
    const data = await response.text().then(txt => {
        const cred = xml2json(txt);
        const cred2: authResponse = JSON.parse(cred);
        const tkn = cred2.elements[0].elements[0].attributes.token;
        return tkn;        
    }).catch(err => console.log(err));
    return data;
}

However it is returning a promise even though I am .then() and .catch() -ing.

If I put a console.log() within the .then(), I am able to see the token that I want. However I'm not able to return it as a value so that it can be stored.

const tkn = getToken().then(data => console.log(data)).catch(err => console.log(err));

I want the value of the token to be returned, not just to be able to console.log() the value I'm looking for. All the examples I am seeing are simply showing that I can console.log() the value I am looking for within the .then(), however that is not what I am trying to do. Sorry if this is not worded correctly would be happy to update with any relevant information needed. Would like to avoid top level await if possible.

  • 2
    Async functions _always_ return promises. – jonrsharpe Apr 07 '22 at 19:20
  • Thanks, so how do I get the value stored from the promise? – clam_clam Apr 07 '22 at 19:31
  • You already know - await it, or use .then. That's it. – jonrsharpe Apr 07 '22 at 19:31
  • I tried to make it clear in initial post - I am using .then() and still do not know how to store the value. How would you go about that? – clam_clam Apr 07 '22 at 19:40
  • You don't. You can't. It's a promise because it's _asynchronous_, the value isn't available yet. Read: https://stackoverflow.com/q/14220321/3001761 – jonrsharpe Apr 07 '22 at 19:41
  • The caller will HAVE to use `.then()` or `await` to get the resolved value of the promise - always. You can see it right in the type definition of your function. It returns a promise (that resolves to a string). So, the return value is a promise. All async functions return a promise - always. – jfriend00 Apr 07 '22 at 21:29

1 Answers1

-1

You seem to be mixing await and .then() / .catch(). Change the second async request to:

try {
    const text = await response.text();
    const cred = xml2json(txt);
    const cred2: authResponse = JSON.parse(cred);
    const data = cred2.elements[0].elements[0].attributes.token;
    return data;
} catch(error) {
  console.log(err);
}
Tyler2P
  • 2,324
  • 26
  • 22
  • 31
  • ```const getToken = async (): Promise => { const response = await fetch('api', { method: 'POST', body: JSON.stringify(body), headers: headers, agent: httpsAgent }) try{ const text = await response.text() const cred = xml2json(text); const cred2: authResponse = JSON.parse(cred); const tkn = cred2.elements[0].elements[0].attributes.token; return tkn; } catch(err){ console.log(err) }; } console.log(getToken());``` still returns promise – clam_clam Apr 07 '22 at 19:36
  • You need to use `await getToken()` or `.then()` / `.catch()` if you don't want top level async operators. Like @jonrsharpe said, it returns a Promise because the operations is asynchronous. – Lambda Calculus Apr 07 '22 at 20:09
  • Not mixing `await` and `.then()` is usually a good style guide to follow, but has nothing at all to do with a solution to the question. The answer to the question is that the `async` function returns a promise - always and no matter what you do inside the function. By specification, every `async` function returns a promise. The caller uses `await` or `.then()` to get the resolved value from that promise. – jfriend00 Apr 07 '22 at 21:29
  • The solution is to use `await` or `.then()` / `.catch()` with `getToken` to get the resolved value of the Promise. – Lambda Calculus Apr 08 '22 at 04:57