Variables and scope

let and const replaced var because they respect block scope, avoiding classic errors inside loops or conditionals. The practical rule is: const by default, let only if the variable will change.

JavaScriptscope.js
const users = ['DOLL', 'JMART', 'FSANC'];

// let: the value changes inside the loop
for (let i = 0; i < users.length; i++) {
  console.log(users[i]);
}

// var "leaks" out of the block — a common source of bugs
if (true) { var leak = 'visible outside the if'; }
console.log(leak); // works, and it shouldn't surprise anyone... but it does

Arrow functions and this

Arrow functions don't have their own this: they inherit it from the context where they are defined. This is key inside SAPUI5 controllers, where losing the controller's this inside a callback is one of the most frequent mistakes.

JavaScriptcontroller-context.js
function Controller() {
  this.contractId = '4500001234';

  // ❌ traditional function: loses the controller's "this"
  this.loadBad = function() {
    setTimeout(function() {
      console.log(this.contractId); // undefined
    }, 200);
  };

  // ✅ arrow function: keeps the lexical "this"
  this.loadGood = function() {
    setTimeout(() => {
      console.log(this.contractId); // '4500001234'
    }, 200);
  };
}
Tip: in a real SAPUI5 controller, the same problem shows up when calling oModel.read(sPath, { success: function(){ ... } }). Using an arrow function there avoids having to save var that = this; before the call.

Asynchrony: Promises and async/await

Almost all communication with the backend (OData, REST APIs) is asynchronous. async/await is syntactic sugar over Promises that makes sequential code more readable than chaining .then().

JavaScriptfetch-contract.js
async function getContract(id) {
  try {
    const response = await fetch(`/odata/Contracts('${id}')`);
    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    const data = await response.json();
    return data;
  } catch (err) {
    console.error('Error loading contract:', err.message);
    throw err;
  }
}

Array methods used every day

map, filter and reduce replace classic loops when transforming or filtering a collection — very common when processing OData read results before rendering them in a table.

JavaScriptarray-methods.js
const contracts = [
  { id: '4500001234', status: 'A', amount: 12000 },
  { id: '4500001235', status: 'P', amount: 4800 },
  { id: '4500001236', status: 'A', amount: 9500 },
];

// filter + map: active only, id only
const activeIds = contracts
  .filter(c => c.status === 'A')
  .map(c => c.id);

// reduce: total amount
const total = contracts.reduce((sum, c) => sum + c.amount, 0);

Destructuring and spread

Extracting properties and combining objects/arrays concisely — very common when normalising OData responses or passing props between components.

JavaScriptdestructuring.js
const contract = { id: '4500001234', manager: 'DOLL', amount: 12000 };

// destructuring with renaming and a default value
const { id, manager: owner, currency = 'EUR' } = contract;

// spread: copy and override a property without mutating the original
const updated = { ...contract, amount: 13500 };
Training Back to index