0

I can't disclose the URL and what API I'm using because it breaches my work's policy but hopefully, I can provide enough information for assistance. I have a JavaScript function that runs on an on-click (I'm eventually building up a form that will make use of this fetch).

function getdata() {
let customer_po = document.getElementById("customer").value;
let access_token;
let data = {
    'grant_type': 'REDACTED'
}
let state = {
    "state": "REDACTED"
}
fetch(prod_auth, {
    method: "POST",
    headers: login_header,
    body: new URLSearchParams(data),
})
    .then(response => response.json())
    .then(result => console.log(result))
}

This works and I can access the dictionary in the console. However, when I try to use my access_token variable declared earlier in such a way:

.then(response => response.json())
.then(result => {access_token = result["access_token"];})

and console.log(access_token) gives undefined. I need to access this variable in my getdata() function so it can be used as a parameter in another fetch call.

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
  • 1
    since Promises are asynchronous, then you can only guarantee access to the result inside the `.then` where the result is ... well ... available - that's how asynchrony works – Bravo May 27 '22 at 01:37
  • Definitely a Dupity dup – JΛYDΞV Jun 02 '22 at 23:35

1 Answers1

0

If you defined and assigned a value to a variable synchronously as you typically do, that variable is available until you leave its scope. For the purpose of this explanation (and generally), JavaScript variables are scoped to the function they run in e.g.

var myVariable = 'acb123';
console.log(myVariable); // 'abc123'

var myFunc = function() {
  var myFunctionVariable = 'def456';
  console.log(myFunctionVariable); // 'def456'
};

console.log(myFunctionVariable); // Uncaught ReferenceEError: myFunctionVariable is not defined

Since you're using promises, you're handling the result of a non-synchronous assignment via functions and the variables you use in each of those callback functions is scoped only to within those functions. While there's no issue in taking a currently scoped variable and writing it out to the console, you'll have the issue you describe when you try to use a variable that's assigned in another non-parent function. You can access the dictionary in your console because you're not actually accessing the variable at that point - you're accessing the object saved in your console.

Going back to your fetch statement, it's making an asynchronous call, so it's not even going to immediately return anything but a promise when assigned. You've already figured out that if you want to do anything with the promise result when it is populated, you need to do so in a chained .then() method. What you're trying to do is then take this asynchronous result and pass it into a variable used and called synchronously and that's not going to work.

Rather, everything you're wanting to do, you must do in subsequent then() methods:

 fetch(prod_auth, {
    method: "POST",
    headers: login_header,
    body: new URLSearchParams(data),
})
  .then(response => response.json())
  .then(result => result["access_token"])
  .then(access_token => {} //Call your next fetch method);

Especially if you're looking at doing more elaborate chains of asynchronous operations, you might also look at using RxJS to somewhat simplify mappings across different chained operations.

Whit Waldo
  • 4,806
  • 4
  • 48
  • 70
  • 1
    Unsurprisingly, this question is asked often. We don't need more answers saying the same thing, so we use duplicate marking as a way to consolidate the best answers in one place. – Heretic Monkey Jun 02 '22 at 23:04
  • Fair enough, but I'd also counter that while I may be able to apply a generic answer to a question myself, it doesn't mean that the generic catch-all answer is the best response to a particular ask. That said, if you've got any links you want to supplement my answer with, don't let me stop you. – Whit Waldo Jun 03 '22 at 09:05
  • sorry for the late reply and duplicate question. but thank you @WhitWaldo I figured it out. – Neil Sharma Jun 08 '22 at 18:35