NUI interfaces (HTML/CSS/JS) · Lesson 3/3 · 9 min

Communicating Lua and JavaScript

Lua sends data to the web page with SendNUIMessage; the web page asks things of Lua with a fetch to a callback.

The NUI and the game are two worlds that talk in two directions: from Lua to JS (to render data) and from JS to Lua (for player actions).

Lua → JS: render data

lua
-- Sends the player's money to the interface
SendNUIMessage({ action = 'setMoney', cash = 1500, bank = 9200 })

client.lua

javascript
window.addEventListener('message', (e) => {
  if (e.data.action === 'setMoney') {
    document.getElementById('cash').textContent = e.data.cash + '€';
    document.getElementById('bank').textContent = e.data.bank + '€';
  }
});

app.js

JS → Lua: an action

javascript
// The player clicks 'Withdraw 100€'
fetch(`https://${GetParentResourceName()}/retirar`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ cantidad: 100 }),
}).then(r => r.json()).then(res => {
  if (res.ok) console.log('withdrawn');
});

app.js

lua
RegisterNUICallback('retirar', function(data, cb)
  -- validate on the SERVER! (server callback)
  ESX.TriggerServerCallback('banco:retirar', function(ok)
    cb({ ok = ok })
  end, data.cantidad)
end)

client.lua

GetParentResourceName() is the name of your resource; the fetch URL is always https://NAME/callbackName. And remember: the JS and the client are NOT trustworthy, the real decision goes on the server.

Practice what you learned

0/3
Test

En una NUI, ¿cómo viaja la información en cada dirección?

Pista

Para PINTAR datos manda Lua; para una ACCIÓN del jugador llama la web.

Rellena los huecos

Completa el fetch del JS hacia un callback de Lua: la URL usa el nombre del recurso y el método es POST.

1fetch(`https://${()}/retirar`, {
2 method: '',
3 body: JSON.stringify({ cantidad: 100 }),
4});
Pista

La URL es https://NOMBRE/callback; NOMBRE lo da GetParentResourceName(). Los callbacks usan POST.

Ordena el código

Ordena el JS que recibe datos de Lua (SendNUIMessage) y pinta el dinero en la interfaz.

Coloca las líneas en el orden correcto con las flechas.

});
window.addEventListener('message', (e) => {
}
document.getElementById('cash').textContent = e.data.cash + '€';
if (e.data.action === 'setMoney') {
Pista

Escucha el evento 'message', comprueba el action, pinta el valor y cierra.

Challenge: code it yourself

Make a 'Refresh' button in the HTML ask Lua for the current money and repaint it.

Write it yourself in your editor (VS Code) and test it on your server. You learn here by doing it, not by copying.

See hint

fetch '/getMoney' → RegisterNUICallback → ESX.TriggerServerCallback → cb with the values.

Escribe aquí tu solución:

How was this lesson?