⏳How to Use Oracle APEX Server Processes with async/await (synchronous)

Tags: #oracleapex #javascript #plsql #asyncawait
🧠 Introduction
When building interactive Oracle APEX apps, you often call Server Processes to fetch or save data — for example, to retrieve employee data from an ORDS REST API or to perform background PL/SQL logic.
But if you use plain JavaScript, your code keeps running without waiting for the server process to finish.
That’s where async/await comes in: it lets you write asynchronous code that looks synchronous, improving readability and control.
In this article, you’ll learn how to run an APEX server process in async mode, using a clean await pattern that returns results just like a native API call.
💡 The Starting Point
Let’s say you have a server process named GET_EMP_DATA that calls an ORDS endpoint and returns employee data.
Your original JavaScript function might look like this:
function get_data(p_url, p_pagination) {
return apex.server.process('GET_EMP_DATA', {
pageItems: "#P28_NEW",
x01: p_pagination,
x02: p_url
}, {
dataType: 'text',
done: function (pData) {
console.log(pData);
alert('pData');
$('#EMP_DATA').append(pData);
}
}, {
loadingIndicator: "#EMP_DATA",
loadingIndicatorPosition: "append"
});
}
Then you try to call it like this:
function run() {
console.log('Start');
var result = get_data('https://apex.oracle.com/pls/apex/ashish_portfolio/hr/test_emp', '2');
console.log(result);
console.log('End');
}
When you run run(), it logs:
Start
[object Object]
End
Because the function does not wait for the server process to complete.
The AJAX request is asynchronous, and the code continues before the result arrives.
🧩 Step 1: Wrap APEX Call in a Promise
The trick is to make get_data() return a Promise that resolves when the APEX process completes.
That way, you can use await to pause execution until the response arrives.
function get_data(p_url, p_pagination) {
return new Promise((resolve, reject) => {
apex.server.process(
'GET_EMP_DATA',
{
pageItems: '#P28_NEW',
x01: p_pagination,
x02: p_url
},
{
dataType: 'text',
success: function (pData) {
console.log('Process success:', pData);
$('#EMP_DATA').append(pData);
resolve(pData); // ✅ returns to await
},
error: function (jqXHR, textStatus, errorThrown) {
console.error('Process error:', textStatus, errorThrown);
reject(errorThrown); // ❌ triggers catch()
}
}
);
});
}
Now the function is Promise-based, and await can be used.
⚙️ Step 2: Use async/await to Wait for the Result
Your run() function can now look like this:
async function run() {
console.log('Start');
try {
const result = await get_data(
'https://apex.oracle.com/pls/apex/ashish_portfolio/hr/test_emp',
'2'
);
console.log('Result:', result);
} catch (err) {
console.error('Error in get_data:', err);
}
console.log('End');
}
When you call run():
Start
(Process success…)
Result: [your API data]
End
This time, the script waits for the server process before logging End.
🧰 Optional: Cleaner Arrow Function
For compact code lovers:
const get_data = (p_url, p_pagination) =>
new Promise((resolve, reject) => {
apex.server.process(
'GET_EMP_DATA',
{ x01: p_pagination, x02: p_url },
{
dataType: 'text',
success: resolve,
error: reject
}
);
});
And then:
(async () => {
const result = await get_data('https://apex.oracle.com/pls/apex/ashish_portfolio/hr/test_emp', '2');
console.log(result);
})();
🧭 Why This Matters
✅ Easier to read: no more nested callbacks
✅ Error handling: handled with standard try...catch
✅ Control flow: you can wait for multiple async calls in sequence
✅ Modern JavaScript: matches current best practices and works seamlessly in APEX 21+
⚡️ Recap
| Concept | Description |
apex.server.process() | Returns a jQuery Deferred object |
Promise | A native JS wrapper for asynchronous results |
await | Waits until a Promise resolves |
async | Declares a function that can use await |
| ✅ Solution | Wrap apex.server.process() inside a Promise and use await |
✨ Final Thoughts
This pattern helps you modernize your APEX front-end JavaScript.
By combining the power of APEX server processes with async/await, your code becomes cleaner, more reliable, and future-proof — perfect for complex UIs that rely on server-side logic.




