I'm struggling to get get javascript Promises to work.
I'm looking for a pointer or two on what I'm doing wrong. Below is my code. I'm trying to convert loadUserPayRateWrapped()
into a function that gets data from a database.
The behavior I'm getting, is that the whole set of wrapper code is still returning before $.getJSON()
has had a chance to get it's data.
The function that is waiting for the data request:
function loadUserPayRateWrapped( projectId )
{
var URI = "/projects/getAssignedResponsibilities?projectId=" + projectId;
$.getJSON( URI, function ( data )
{
if ( data === null )
return getDataFromCookie( "payRate" );
else
{
const employeeId = getDataFromCookie( "empId" );
if ( data[ 0 ].alternatePay === null )
return getDataFromCookie( "payRate" );
var altPayArray = JSON.parse( data[ 0 ].alternatePay );
$.each( altPayArray, function ( idx, element )
{
if ( element.uid == employeeId )
return element.pay;
} );
}
// nothing was found, so return the regular pay rate
return getDataFromCookie( "payRate" );
});
}
The wrapper promise function:
function loadUserPayRatePromise( projectId )
{
var payRateProm = new Promise((resolve, reject) =>
{
var payRate = loadUserPayRateWrapped( projectId );
resolve( payRate );
});
payRateProm.then( result => { return payRate } );
}
The async caller:
async function loadUserPayRate( projectId )
{
try
{
const pay = await loadUserPayRatePromise( projectId );
return pay;
}
catch(error)
{
}
}
code from the mainline that wants the data:
// add the default pay rate for this user
var payRate = loadUserPayRate( data.projectId );
$( "#hourlyRate" ).val( payRate.toFixed(2) ); //payRate must be populated before this line
Just "convert" $.getJSON
from callback style to Promise is required and enough.
This is my example, maybe you have handle error case by yourself.
function loadUserPayRateWrapped(projectId) {
return new Promise((resolve, reject) => { // wrap callback function into a promise
var URI = "/projects/getAssignedResponsibilities?projectId=" + projectId;
$.getJSON(URI, function (data) {
const defaultPayRate = getDataFromCookie("payRate"); // extract to variable to reuse
if (data === null) { // recommend style: if block with {}
return resolve(defaultPayRate);
} else {
const employeeId = getDataFromCookie("empId");
if (data[0].alternatePay === null) {
return resolve(defaultPayRate);
}
var altPayArray = JSON.parse(data[0].alternatePay);
var foundAltPay = altPayArray.find(p => p.uid === employeeId); // why $.each ??
// nothing was found, so return the regular pay rate
return resolve(foundAltPay || defaultPayRate)
}
});
});
}
Now, loadUserPayRateWrapped
return a Promise. Then you can use Promise style to call the function, or use async/await
style:
// Promise style
loadUserPayRateWrapped(data.projectId)
.then(payRate => {
$("#hourlyRate").val(payRate.toFixed(2));
});
// async/await style with IIFE
(async () => {
const payRate = await loadUserPayRateWrapped(data.projectId); // wait
$("#hourlyRate").val(payRate.toFixed(2));
})();