Literales de plantilla con un ForEach en él

4 minutos de lectura

Avatar de usuario de Steven
steven

¿Es posible devolver un valor de cadena en ForEach en un literal de plantilla para que se agregue en ese lugar? Porque si lo registro vuelve undefined. ¿O es que como escribí no es posible en absoluto?

return `<div>
                <form id='changeExchangeForViewing'>
    <label for="choiceExchangeForLoading">Change the exchange</label>
    <div class="form-inline">
    <select id='choiceExchangeForLoading' name="choiceExchangeForLoading" class="form-control">

    ${Object.keys(obj).forEach(function (key) {
        return "<option value="" + key + "">" + obj[key] + "</option>"           
    })}
    `;

  • Relacionado con mi comentario a continuación: jsfiddle.net/Lwt6aLyp/1

    usuario8897421

    21 de enero de 2018 a las 15:36

Avatar de usuario de TJ Crowder
TJ Crowder

No porque forEach ignora el valor de retorno de su devolución de llamada y nunca devuelve nada (por lo tanto, llamarlo da como resultado undefined).

Estas buscando mapque hace exactamente Lo que quieras:

return `<div>
    <form id='changeExchangeForViewing'>
        <label for="choiceExchangeForLoading">Change the exchange</label>
        <div class="form-inline">
            <select id='choiceExchangeForLoading' name="choiceExchangeForLoading" class="form-control">
                ${Object.keys(obj).map(function (key) {
                    return "<option value="" + key + "">" + obj[key] + "</option>"
                }).join("")}
`;

Tenga en cuenta que después del mapeo, el código usa .join("") para obtener una sola cadena de la matriz (sin ningún delimitador). (Me olvidé de esto inicialmente, he estado haciendo demasiadas cosas de React, pero stephledev lo señaló en su respuesta).

Dicho esto, podría ser más fácil de leer si lo divide, y puede usar una función de flecha en lugar de una función tradicional, tal vez con otra plantilla literal:

const options = Object.keys(obj).map((key) =>
    `<option value="${key}">${obj[key]}</option>`
);
return `<div>
    <form id='changeExchangeForViewing'>
        <label for="choiceExchangeForLoading">Change the exchange</label>
        <div class="form-inline">
            <select id='choiceExchangeForLoading' name="choiceExchangeForLoading" class="form-control">
                ${options.join("")}
`;

Finalmente, mencionaré Object.entriesque te da una flecha de [key, value] matrices, que usted podría desea utilizar en el mapeo de las opciones (o no, Object.keys también está bien):

const options = Object.entries(obj).map((key, value) =>
    `<option value="${key}">${value}</option>`
);
return `<div>
    <form id='changeExchangeForViewing'>
        <label for="choiceExchangeForLoading">Change the exchange</label>
        <div class="form-inline">
            <select id='choiceExchangeForLoading' name="choiceExchangeForLoading" class="form-control">
                ${options.join("")}
`;

Nota al margen: Eso no es un “literal de cadena”, es un modelo literal.

  • Creo que hay como 15 minutos en los que no puedes aceptar

    – mdatsev

    21 de enero de 2018 a las 15:21

  • @ nitte93user3232918 Necesito esperar 9 minutos

    – Esteban

    21 de enero de 2018 a las 15:22

  • Sugeriría que sería una mejor forma mover el código a una función para mejorar la limpieza y para que se pueda usar un literal de plantilla separado dentro de la devolución de llamada.

    usuario8897421

    21 de enero de 2018 a las 15:28

  • @rockstar: Sí, estoy totalmente de acuerdo.

    –TJ Crowder

    21 de enero de 2018 a las 15:32

  • @GalibHasanov – Porque el resultado de llamar forEach es siempre undefinedpero el resultado de llamar map es una matriz con los contenidos asignados.

    –TJ Crowder

    1 de diciembre de 2018 a las 17:13

Ya que map() devuelve una matriz, la respuesta de @TJ Crowder producirá HTML no válido como el toString() El método de una matriz se llamará dentro del literal de la plantilla, que usa comas para delimitar la matriz. Para solucionar esto, simplemente agregue join('') para usar explícitamente ningún delimitador:

${Object.keys(obj).map(key => (
    `<option value="${key}">${obj[key]}</option>`
)).join('')}

Además, puede usar literales de plantilla dentro del propio mapa.

  • Es más útil, cuando vea una omisión menor como esa, comentar y avisar al que responde. (¡He estado haciendo demasiado React últimamente!) SO está destinado a ser colaborativo.

    –TJ Crowder

    1 de diciembre de 2018 a las 17:12


  • Para su información, cualquiera que lea estos comentarios sobre la respuesta de stephledev, la solución está integrada en la respuesta aceptada, por lo que no hay nada que ver aquí. 😉

    – bugmenot123

    5 de noviembre de 2019 a las 8:58

  • Exactamente lo que estaba buscando en literales.

    – sg28

    29 de octubre de 2021 a las 2:10

¿Ha sido útil esta solución?