Use JavaScript for short property expressions, formatting, validation, and UI glue.
Heavy computation and blocking I/O stall the GUI thread and belong behind the project's service boundary.
property string displayName: user?.name ?? "Anonymous"
function clamp(value: real, minimum: real, maximum: real): real {
return Math.max(minimum, Math.min(maximum, value))
}
Bindings observe QML property notifications.
Deep mutation of a plain JavaScript object or array does not emit those notifications, so replace the value or use an observable model/object.
Deferred calls
function refreshLater(): void {
Qt.callLater(refresh)
}
Qt.callLater(callback, ...args) asks the event loop to invoke a callback later.
Repeated pending calls to the same function are coalesced; the last supplied arguments are used.
It neither returns a Promise nor moves work off the GUI thread.
Do not defer side effects merely to hide a binding loop.
Fix ownership and dependencies first; defer only when later event-loop ordering is the actual requirement.
Use the asynchronous API already provided by the application boundary for network, disk, and long-running work.
Do not introduce another runtime merely to avoid designing that boundary.
# JavaScript in QML
Use JavaScript for short property expressions, formatting, validation, and UI glue.
Heavy computation and blocking I/O stall the GUI thread and belong behind the project's service boundary.
```qml
property string displayName: user?.name ?? "Anonymous"
function clamp(value: real, minimum: real, maximum: real): real {
return Math.max(minimum, Math.min(maximum, value))
}
```
Bindings observe QML property notifications.
Deep mutation of a plain JavaScript object or array does not emit those notifications, so replace the value or use an observable model/object.
## Deferred calls
```qml
function refreshLater(): void {
Qt.callLater(refresh)
}
```
`Qt.callLater(callback, ...args)` asks the event loop to invoke a callback later.
Repeated pending calls to the same function are coalesced; the last supplied arguments are used.
It neither returns a Promise nor moves work off the GUI thread.
Do not defer side effects merely to hide a binding loop.
Fix ownership and dependencies first; defer only when later event-loop ordering is the actual requirement.
Use the asynchronous API already provided by the application boundary for network, disk, and long-running work.
Do not introduce another runtime merely to avoid designing that boundary.