0

I have an object array of users, which each object has 'username' and 'password'.

There is then a login page, where once the user enters in a username and a password, I want to pass that into the reducer and compare them with each object in the 'users' array, and if an object that matches both, 'password' and 'username', is found, I want it return 'true'.

Following is the reducer:

const usersReducer = function(users = [], action){
  switch (action.type){

    case 'VERIFY_USER':
        return users.map((user)=> {
          if(user.username === action.username && user.password ===  action.password){
            return true
          } else{
          return false
          }
        })
      }

    default:
      return users
  }
}

But it seems to return true all the time. Am I using map correct? If not, is there such a method where it'll go through each object in an array? Any insight or guidance would be appreciated. Thank you in advance!

EDIT** Calling it from the following:

  verifyLoginUser(){
    event.preventDefault()

    if(this.props.actions.verifyUser(this.props.loginUser.username, this.props.loginUser.password)){
      console.log('LOGGED IN')
    } else {
      console.log('NOT LOGGED IN')
    }
  }

With the following reducer:

case 'VERIFY_USER':
  let isVerified = false;
  users.forEach((user)=> {
    if(user.username === action.username && user.password ===  action.password){
      isVerified = true;
      return false;
    }
  });
  return isVerified;
7
  • Array.find Commented Jul 12, 2016 at 1:46
  • hopefully this is just something you're making for fun and not actually releasing, as storing+checking the passwords the way you're doing it is about as insecure as you can get Commented Jul 12, 2016 at 1:48
  • @Hamms not hooked up to a safe backend yet. this is just for testing and learning. appreciate the concern! Commented Jul 12, 2016 at 1:50
  • @Hamms could you provide an example? Commented Jul 12, 2016 at 1:50
  • return users.find(user => user.username === action.username && user.password === action.password) Commented Jul 12, 2016 at 2:04

3 Answers 3

1

Use Array.some

return users.some(user => user.username === action.username && user.password === action.password);
Sign up to request clarification or add additional context in comments.

2 Comments

they want to actually retrieve the relevant user
@Hamms He/she said I want it return 'true'., so this will be fine for him/her.
0

Map function would return you an array. I suggest using a different native array function: 'find'. To check if user object exists in the array of users, you can do

function findUser(user) { 
    return (user.username === action.username && user.password === action.password);
}

var isUser = users.find(findUser) ? true : false;
return isUser;

Comments

0

use a boolean variable and forEach to accomplish what you want

case 'VERIFY_USER':
    let isVerified = false;
    users.forEach((user)=> {
        if(user.username === action.username && user.password ===  action.password){
            isVerified = true;
            return false;
        } 
    });
    return isVerified;

to take this a step further lets say you wanted to iterate on this and return the correct user so that way you can populate a currentUser with it or something.

case 'VERIFY_USER':
    let currentUser = null;
    users.forEach((user)=> {
        if(user.username === action.username && user.password ===  action.password){
            currentUser = user;
            return false;
        } 
    });
    return currentUser;

EDIT: to what we were talking about in the comments

lets say you make a request to login a user somewhere. and the function lives on your props

this.props.loginUser({my params here});

now your actual action.

loginUser = (data) => {
    // whatever method you are using to make the request goes here.
    someRequestMethod('/login/, data).then( (response) => {
        if(response.status === 200){
            dispatch(type: USER_LOGIN, payload: response.data); // whatever the user is that comes back from the response. I just put data for an example
        }
    })
}

now in your reducer

const populateState = (user) => {
    return {
        id: user.id,
        username: user.username,
        email: user.email,
        isAuthenticated: Object.keys(user).length > 0
    };
}
let defaultState = {id: null, username: '', email: '', isAuthenticated: false};
const loginReducer = (currentUser = defaultState) => {
    switch (action.type){
        case 'USER_LOGIN':
            return Object.assign({}, currentUser, populateState(action.payload));
    return currentUser;
}

finally, everywhere else you just look for the current user.

if(this.props.currentUser.isAuthenticated){
    // do stuff
}

14 Comments

Sorry but why is it returning false inside the if-statement.
@JoKo the return false is just to break the forEach loop. you are returning (to redux) isVerified which is set to true when you have a correct value. (the forEach defaults to returning true so that the next iteration of the for loop will happen. i'm breaking out of that loop because we already found the correct person).
Appreciate the clarification but still don't seem to work as intended. Is it possible to open up a chat? Would really appreciate it. Been stuck on this since yesterday..
Try printing out the user in each iteration of the forEach
@JoKo also try printing out the action.username and password too.. I assume it may be a lowercase uppercase issue or something. where your comparison is not working properly
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.