0

It's the first time I use promises in JavaScript so I apologise in advance if this is a dumb question. I need to fetch a field from an API call and use it in another function. This is my code:

async function getComposerName() {

  try {
    let composerID = document.querySelectorAll('#addCompositionFromPerformanceForm select')[0].value
    let url = 'http://151.236.37.122/api/profiles/' + composerID + '/?format=json';
    let response = await fetch(url);

    let composition = await response.json(); // read response body and parse as JSON

    console.log(composition['user']); // This correctly returns the name of the composer in the console at the end of addComposition() is run.

    let ComposerName = composition['user'] // this is a valid value when run in the browser's console

    return ComposerName;
}
  catch(error){
    console.log('error')
  }
}


function full_title(){

  var title = document.querySelectorAll('#addCompositionFromPerformanceForm input')[1].value

  let fullTitle = title + ', by ' + getComposerName()

  return fullTitle;
}


function addComposition (oFormElement) {

  if ( confirm("Are you sure you wish to add " + full_title() + " to the database?") == false ) {
       return false ;
    } else {
[other stuff]

When I call the addComposition() function (it's a form submit) I get the alert message with this text:

Are you sure you wish to add My Title, by [object Promise] to the database?

Of course I'd like to see the composer's name instead of [object Promise]. The funny thing is that when I click on 'cancel' I see the composer's name popping up in the console log, which means, I suppose, that the promise gets fulfilled after the whole code in addComposition() is run. Am I right? How do I get the composer's name in my alert message?

Thanks.

HBMCS
  • 686
  • 5
  • 25
  • 2
    [`async` function return value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function#Return_value): _"**A `Promise`** which will be resolved with the value returned by the `async` function, or rejected with an exception thrown from, or uncaught within, the `async` function."_ – Andreas May 11 '20 at 12:59
  • Your composer check is asynchronous. You cannot use its result synchronously, because it hasn't provided that result yet. – T.J. Crowder May 11 '20 at 13:01
  • Thank you both. The thing is that I need to fetch the composer's name from my API and then use it in my code. If I just open an ajax call within my code and get it from there, then that value is not available outside the ajax call. Am I right? – HBMCS May 11 '20 at 13:02
  • @T.J. Crowder I still don't understand though Even adding let full_title = title + ', by ' + (await getComposerName(); return composer })() doesn't do the trick. – HBMCS May 11 '20 at 13:41
  • @HBMCS - In the code you have above, that would be a syntax error, because you can only use `await` in an `async` function and the function that code (or rather, the code setting `fullTitle`) is in isn't `async`. But you're on the right track: If **all** of the functions involved were `async` functions, you could do that. Just be sure that whatever's calling the entry point to that call chain understands that what it gets back is a promise. – T.J. Crowder May 11 '20 at 13:48
  • @T.J.Crowder sorry, I meant let full_title = title + ', by ' + (async function(){ let composer = await getComposerName(); return composer console.log(composer); })() This still returns object Promise. I've even added 'async' before all my functions as you suggested, and I still get the object thing. Sigh. – HBMCS May 11 '20 at 13:51
  • @HBMCS - Again, `async` functions return promises. You can't use the result of calling an `async` function synchronously. All you've done there is add another `async` wrapper around it, but not fundamentally changed anything. – T.J. Crowder May 11 '20 at 14:04

0 Answers0