Necesito implementar el filtrado de usuarios de acuerdo con las reglas que vienen con el archivo JSON junto con los usuarios. Hay dos tipos de reglas: "excluir" e "incluir". Pueden venir individualmente o dos a la vez. En este momento, mi código funciona bien cuando entran dos reglas a la vez. Pero cuando solo hay una regla, el error en la consola es No se pueden leer las propiedades de undefined (leyendo 'forEach'). ¿Cómo se puede resolver este problema?
Usuarios y reglas:
{ "data": [{ "user": "user1", "city": "New York", "disabled": false }, { "user": "user2", "city": "London", "disabled": false }, { "user": "user3", "city": "Tokyo", "disabled": true } ], "condition": { "exclude": [{ "disabled": true }], "include": [{ "city": "New York", }], } } const data = responseJson.then((data) => { var filteredUsers = advancedFilter(data.data, data.condition); console.log(filteredUsers); }); function advancedFilter(data, condition) { return data.filter((dataItem) => { var cond = true; if ("exclude" in condition || "include" in condition) { condition.exclude.forEach((condItem) => { for (var key in condItem) { cond = cond && dataItem[key] !== condItem[key]; } }); condition.include.forEach((condItem) => { for (var key in condItem) { cond = cond && dataItem[key] === condItem[key]; } }); } return cond; }); }Solo necesita hacer dos condiciones if por separado, por lo que si hay una condición de exclude , ejecute forEach en la exclusión. Además, si hay una condición de include , ejecute forEach en la inclusión.
El error ocurre porque realiza un bucle para include y exclude incluso si uno de ellos no existe.
const responseJson = { "data": [{ "user": "user1", "city": "New York", "disabled": false }, { "user": "user2", "city": "London", "disabled": false }, { "user": "user3", "city": "Tokyo", "disabled": true } ], "condition": { "exclude": [{ "disabled": true }], "include": [{ "city": "New York", }], } } var filteredUsers = advancedFilter(responseJson.data, responseJson.condition); console.log(filteredUsers); function advancedFilter(data, condition) { return data.filter((dataItem) => { var cond = true; if ("exclude" in condition) { condition.exclude.forEach((condItem) => { for (var key in condItem) { cond = cond && dataItem[key] !== condItem[key]; } }); } if ("include" in condition) { condition.include.forEach((condItem) => { for (var key in condItem) { cond = cond && dataItem[key] === condItem[key]; } }); } return cond; }); }Recomendaría dividir la lógica en dos declaraciones if, así:
if ("exclude" in condition) { condition.exclude.forEach((condItem) => { for (var key in condItem) { cond = cond && dataItem[key] !== condItem[key]; } }); } if ("include" in condition) { condition.include.forEach((condItem) => { for (var key in condItem) { cond = cond && dataItem[key] === condItem[key]; } }); }De esta manera, no intentará leer algo indefinido, ya que habrá verificado que la propiedad está presente.