Link to home
Start Free TrialLog in
Avatar of Michael Vasilevsky
Michael VasilevskyFlag for United States of America

asked on

Populating a Form Using Promises or Async/Await

I'm trying to populate a form using JavaScript promises or async/await (or similar) but just can't seem to get it. I tried .then and Promise.all with the same result: if one of the "get" functions takes longer than the getPunchlistItem function, the actual value is overwritten.

var myFSEs = [];
var myTypes = [];
var myPeople = [];

$(document).ready(function () {
  getFSEs("itemFSE", "Select FSE...")
    .then(getPersons("itemResponsible", "Select Person..."))
    .then(getTypes("itemType", "Select Type..."))
    .then(getPunchlistItem(myPLItemID));
 //or
  Promise.all([getFSEs("itemFSE", "Select FSE..."), getPersons("itemResponsible", "Select Person..."), getTypes("itemType", "Select Type...")]).then(function () {
    getPunchlistItem(myPLItemID);
  });
});

Open in new window


My async functions look like:

async function getFSEs(el, allText, filter) {
   let result = await getJson(myURL + "PunchlistTracking/_api/web/lists/getbytitle('FSEs')/items", function (data) {
   myFSEs = data.d.results.map(FSE => [`${FSE.Id}`, `${FSE.Title}`, `${FSE.FSEName}`]);
   var output = `<option value='0' selected='selected'>${allText}</option>`;

    for (var i = 0; i < myFSEs.length; i++) {
        if (`${myFSEs[i][3]}` == filter || !filter) {
            output += `<option value='${myFSEs[i][0]}'>${myFSEs[i][1]} ${myFSEs[i][2]}</option>`;
        }
    };

    $(`#${el}`).html(output);
    }, logError);

    return result;
}

function getJson(endpointUrl, success, failure) {
  $.ajax({
    type: "GET",
    headers: {
        "accept": "application/json;odata=verbose",
        "content-type": "application/json;odata=verbose"
    },
    url: endpointUrl,
    success: success,
    failure: failure
  });
}   //  getJson

Open in new window


User generated image
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Can you explain rather what you are trying to get your form to do?
Avatar of Michael Vasilevsky

ASKER

Sure, I want to populate the dropdowns (FSE, Type, and Responsible) via functions like getFSEs, and then populate the form fields with the values specific to the item selected on the previous page. My issue is sometimes the getFSEs, getTypes, or getResponsible dropdowns are populated after the form is populated with specific values. I'm trying to resolve that issue by using async await. With the above code sometimes the dropdowns are still populated after the form, and I'm not understanding why.

Let me know if you need more detail!
SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
This code is populating the form for editing existing data. I open the page, populate the dropdowns dynamically, and then populate the existing data. Then the user can edit the data and send it back the server.

I want getPunchlistItem to be called only after getFSEs, getPersons, and getResponsible have resolved.
Is there a reason you are making multiple calls to get the data? Is it being sorced from different locations?

If not I would make one call - get the data in a single shot and popluate the form in one go.
Yes these are separate REST calls to individual SharePoint lists.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Glad you got an answer however I don't think the one you have is the best approach.
The await's in your code are going to block - if each of those calls takes 2 seconds your app is going to wait 8 seconds for all of them to complete.

If it were me I would make a new server side REST endpoint that fetches all the data at once and sends it back as a single response.
Thanks for the comment Julian. This is SharePoint Online so I’m limited to the endpoints provided by Microsoft.
Is it not possible to wrap them server side in your own REST endpoint? SP not my strong point so just putting this out there in case it is useful.
We can’t do anything server side with SharePoint Online. Makes for some interesting development situations :)
Ok understood.
Solved it!