Search code examples
javascriptarrayswebrtc

Why can we omit a return statement in this usage of the method map()


I am currently going over the WebRTC tutorial on their docs when I noticed that they use forEach after their usage of map(). In order to use forEach and expect a value instead of undefined array, map() would have needed to return an array, which I don't see how it can, because it doesn't return anything.

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));
}

Solution

  • The code will not work since the map returns nothing.

    Here is an alternative method

    function updateCameraList(cameras) {
      document.getElementById('availableCameras').innerHTML = cameras
      .map(({label, deviceId}) => `<option value="${deviceId}">${label}</option>`)
      .join(""); 
    }
    

    I learned today that we now can use label instead of text

    https://jsfiddle.net/mplungjan/osyLzqk2/

    Here is a safer version since there is a tiny possibility for XSS

    function updateCameraList(cameras) {
      const sel = document.getElementById('availableCameras')
      cameras.forEach(({label, deviceId}) => {
        const option = new Option(label,deviceId); 
        sel.add(option)
      })
    }
    

    And here is a non working attempt of XSS - at least it does nothing in 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>