0

I have this block of code that returns access_token for login

async function login(username, password) {
  await $.ajax({
    url: "/api/login",
    type: "POST",
    data: `{"username": "${username}", "password": "${password}"}`,
    dataType: "text",

    success: async function(response) {
      var a = await JSON.parse(response)
      console.log(a.token.access_token)
      return a.token.access_token
    },

    error: function(response) {
      return "false"
    }
  })
}

It is returning

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRob3JpemVkIjp0cnVlLCJleHAiOjE2MTgzODIzNzUsInVzZXJuYW1lIjoic2sxMTIyIn0.e16nHpJUsNmMSAcPgaHkmJgwrnBkp4jB7KHe_ylAvKc // console.log() from login()

undefined // console.log() in another function
console.log(await login(questions[0].value, questions[2].value))

Am I wrong in Using Async/Await? or is it something else?

1 Answers1

2
  • You need to use the Promise semantics of $.ajax(), the success callback will not work for return values.
  • You need to return the promise from the $.ajax() call.
  • Absolutely nothing inside your login() function needs to be async or await.

Correct code:

function login(username, password) {
  return $.ajax({
    url: "/api/login",
    type: "POST",
    data: {
      username: username,
      password: password
    },
    dataType: "text"
  }).then(function (response) {
    var data = JSON.parse(response);
    return data.token.access_token;
  }).fail(function (jqXhr, status, error) {
    return false;
  });
}

and

console.log(await login(questions[0].value, questions[2].value));

It makes no sense to set dataType: "text" when you're expecting JSON from the server. Set the Content-Type: application/json header in your server response, drop the dataType parameter, and jQuery will even automatically parse the JSON for you.

function login(username, password) {
  return $.post("/api/login", {username: username, password: password})
    .then((data) => data.token.access_token)
    .fail((jqXhr, status, error) => false);
}

If you want, you can turn that into an async/await based function:

function login(username, password) {
  try {
    const data = await $.post("/api/login", {username: username, password: password});
    return data.token.access_token;
  } catch (err) {
    return false;
  }
}
Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • Thanks it Worked. I think it is because we are also returning ajax call so it will wait? is it correct? – Satyam Kulkarni Apr 14 '21 at 06:30
  • @SatyamKulkarni In principle, yes - any function call that is supposed to work with `await` needs to return a Promise. So if you want to make your `login()` function `await`able, it needs to return a Promise. `$.ajax()` produces a promise, so return it. But *if* you're returning a Promise, then useing `await` inside of the `login()` function is not necessary anymore. It's enough when your code waits in one place for the result, and that place is the line where you use `await login(...)`. – Tomalak Apr 14 '21 at 06:34