Actualmente estoy revisando el tutorial de WebRTC en sus documentos cuando noté que usan forEach después de usar map(). Para usar forEach y esperar un valor en lugar de una matriz indefinida, map() habría necesitado devolver una matriz, lo cual no veo cómo puede hacerlo, porque no devuelve nada.
function updateCameraList(cameras) { const listElement = document.querySelector('select#availableCameras'); listElement.innerHTML = ''; cameras.map(camera => { const cameraOption = document.createElement('option'); cameraOption.label = camera.label; cameraOption.value = camera.deviceId; }).forEach(cameraOption => listElement.add(cameraOption)); }El código no funcionará ya que el mapa no devuelve nada.
Aquí hay un método alternativo.
function updateCameraList(cameras) { document.getElementById('availableCameras').innerHTML = cameras .map(({label, deviceId}) => `<option value="${deviceId}">${label}</option>`) .join(""); }Hoy aprendí que ahora podemos usar etiquetas en lugar de texto
https://jsfiddle.net/mplungjan/osyLzqk2/
Aquí hay una versión más segura ya que hay una pequeña posibilidad para XSS
function updateCameraList(cameras) { const sel = document.getElementById('availableCameras') cameras.forEach(({label, deviceId}) => { const option = new Option(label,deviceId); sel.add(option) }) }Y aquí hay un intento de XSS que no funciona, al menos no hace nada en Chrome
const cameras = [{ deviceId : `xss"></option></select><img src="x" onerror="alert(1)" />` , label:"bla" }] function updateCameraList(cameras) { const xssString = cameras .map(({label, deviceId}) => `<option value="${deviceId}">${label}</option>`) .join("") console.log(xssString) document.getElementById('availableCameras').innerHTML = xssString; } updateCameraList(cameras) <select id="availableCameras"></select>Claramente al código le falta una línea. El código debería insertarse indefinido en una matriz y eso se agregaría a la selección.
function updateCameraList(cameras) { const listElement = document.querySelector('select#availableCameras'); listElement.innerHTML = ''; cameras.map(camera => { const cameraOption = document.createElement('option'); cameraOption.label = camera.label; cameraOption.value = camera.deviceId; return cameraOption; }).forEach(cameraOption => listElement.add(cameraOption)); }Ahora, ¿por qué tendríamos que hacer un bucle dos veces? Es una pérdida de tiempo. Así que solo haría un bucle una vez.
function updateCameraList(cameras) { const listElement = document.querySelector('select#availableCameras'); listElement.innerHTML = ''; cameras.forEach(camera => { const cameraOption = document.createElement('option'); cameraOption.label = camera.label; cameraOption.value = camera.deviceId; listElement.add(cameraOption)); }); }