If always returning false no reduce()

Asked

Viewed 62 times

1

I’m trying to make a simulation of what would be an authentication process with pure js (just to dominate arrays), I already managed with other methods like filter, find, some, for, foeach etc. But with reduce, the if that would check the data always returns false, independent of the input "user". I’ve tried every possible statement yet the result is always the same

//função que seria chamada por um form
function auth() {       
    
    //inputs do usuário 
    var usernameInput = "a";
    var passwordInput = "a";

    //este seria o banco de dados
    const users = [
        {
            username: "a",
            password: "aa"
        },
        {
            username: "b",
            password: "bb"
        },
        {
            username: "c",
            password: "cc"
        }
    ];

    //hashmap pra percorrer o banco de dados 
    return users.reduce((msg, elemento) => {
        //ifs que retornariam uma mensagem para o usuário
        if (elemento.username == usernameInput && elemento.password == passwordInput) {
            return msg = 'log successful!';
        }
        //este sempre é o retorno :|
        else {
            return msg = 'wrong username or password';
        }
        if(!usernameInput || !passwordInput) {
            return msg = 'empty username or password';
        }
    },0);

}

  • 3

    What would you like the reduce to return? Reduce is to reduce arrays to a single value (for example, in single number arrays, the sum of these numbers).

1 answer

2


It makes no sense to use reduce for that reason

Read the documentation to understand what reduce makes. Basically, it takes a function, executes this function for each element of the array and combines the results. The documentation itself has several examples use (for example, to sum all the numbers of an array, among others).

But you do not want to combine the processing results of the array items. What you want to do is check if one of the elements in the array has certain data. In this case, don’t invent, use a for:

function auth(users, username, password) {
    for (let user of users) { // faz um loop por todos os users
        if (user.username == username && user.password == password) {
            return true; // encontrei, retorna true
        }
    }
    // se chegou aqui é porque não encontrou ninguém, retorna false
    return false;
}

const users = [
    { username: "a", password: "aa" },
    { username: "b", password: "bb" },
    { username: "c", password: "cc" }
];

console.log(auth(users, 'a', 'a')); // false
console.log(auth(users, 'a', 'aa')); // true

I also changed the function auth to receive as parameters the array of users, in addition to the user and password that must be searched. Thus the function becomes more generic and can be reused - this is the idea of functions, in fact, being able to reuse the same algorithm for different parameters. The way you did, it only worked for a specific group of users, but doing it the way above, you could use another array of users, for example, that would work smoothly.

And made the function return only true or false (found or not the user/password). Because then who called the function do what you want with the result (can even show some message). I think better because if the function returned the message you would be very dependent on the specific text, already returning only one Boolean you can change the message at will:

if (auth(users, username, password)) {
    // autenticado: mostra uma mensagem qualquer
} else {
    // não autenticado: mostra outra mensagem
}

// *** As mensagens podem ser mudadas sem precisar mudar a função ***

This is better, because if the function returned its own message, you would have to do something like:

if (auth() == 'log sucessful!') {
    ...
}

And if one day the message changed, you would have to change all the if's that verify the return of the function.


In your case you want a specific message if the data is blank, then just have another if:

if (!username || !password) {
    // mensagem dizendo que os dados estão em branco
} else if (auth(users, username, password)) {
    // autenticado: mostra uma mensagem qualquer
} else {
    // não autenticado: mostra outra mensagem
}

Because if it’s blank, it wouldn’t even be worth calling the authentication function - after all, I understand that validating the data (check if they were filled out) is a different action of authenticating (check if the user and password match), so I would leave it out of the function auth.


Finally, another alternative is to use some, that checks if any of the array elements match the given criteria:

function auth(users, username, password) {
    return users.some(user => user.username == username && user.password == password);
}

And of course, the for more traditional:

function auth(users, username, password) {
    for (let i = 0; i < users.length; i++) { // faz um loop por todos os users
        if (users[i].username == username && users[i].password == password) {
            return true; // encontrei, retorna true
        }
    }
    // se chegou aqui é porque não encontrou ninguém, retorna false
    return false;
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.