0

I am currently making up a sign up form using react and firebase, and I got stuck at validating whether the username given by the user has been used or not by checking the user list from firebase. Here's a simplified version of my code:

import React, { Component } from 'react';
import * as firebase from 'firebase';

const userList = []

class SignUpForm extends Component {
    constructor() {
        super();
        /*initialize my state*/
    }

    //get the user list from the database
    componentWillMount() {
        const users = database.ref('users')
        users.once('child_added', snapshot => {
          userList.push(snapshot.val())
        })
    }

    /*functions that get username from input and store into the state*/

    validateForm() {
        //in this.state, 'username' is the text input that the user entered
        const { username } = this.state

        //this is the function that checks if the username is already in use
        const findUsername = (username) => {
          userList.map(user => {
            if (user.username === username) {
              console.log("test")
              return true
            }
          })
        }

        //if username has been taken
        if (findUsername(username)) {
          console.log("found the same username in the database")
        }

        /*other validation checks*/
    }

    render() {
        return(
            <div>
                {/*input elements, etc*/}
                <button onClick={this.validateForm}
            </div>
        )
    }
}

The problem is, when I do console.log(findUsername(username)), it returns undefined in my console. However, it still logs the string "test", and runs anything written inside that function. It just doesn't return true inside the if statement. I have done many checks in my code, and I can make sure that:

  • the array userList contains every user I have stored in firebase
  • this.state.username is the actual text input that the user enters
  • console.log(user.username === username) when iterating through userList returns true
  • render() function works properly

This is my first time asking a question on Stack Overflow, and I apologize if there is any ambiguity or lack of information in my post.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807

2 Answers2

1

Your return true is returning from the anonymous function that you passed to userList.map(), not from the function findUsername. userList.map() won't propagate that return value from the inner anonymous function.

If you want to know if the userList array contains some string, it's not clear to me at all why you're using map(). It seems to me if you want a boolean that indicates if an array contains a string, you'd want to use contains() instead:

return userList.contains(username)
Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • Thanks for your answer, it was indeed the case! I used .map() since the userList array contains of objects that have properties of username, email, name, surname, etc. and I would like to only select the username property of each user, so I thought using .map() would be the solution – aboudicheng Jun 17 '18 at 21:59
1

Since the function does not return anything, console log is undefined. You are returning true inside the map, but the findUsername itself does not return anything. To check if a user exists, you can simply do this.

const hasUser = userList.find(user => user.username === username);
if(!hasUser) {
  //no user present. you can proceed further.
}
Ravi Theja
  • 3,371
  • 1
  • 22
  • 34