简体   繁体   中英

'.filter is not a function' error message in React app when deployed to Heroku but not when running locally

I thought I was at the end of the very long road to getting my first full-stack app deployed...

Everything works fine when running locally but when using a login function on the version hosted on Heroku I get an error message "Uncaught TypeError: t[0].filter is not a function".

I'm not sure why it should work locally but not on Heroku when in theory the code is identical. This is the code for the login function which seems to be what's causing the issue.


    const usersContext = useContext(UsersContext)

    const { users, showRegisterModal, showRegisterSuccessDialog, setCurrentUser, getUsers } = usersContext

    useEffect(() => {
      getUsers()
    }, [])

    const [loginDetails, setLoginDetails] = useState({
        loginEmail: '',
        loginPassword: ''
    })

    const { loginEmail, loginPassword } = loginDetails

    const onChange = (e) => {
        setLoginDetails({ ...loginDetails, [e.target.name]: e.target.value })
    }

    const onSubmit = (e) => {
        e.preventDefault()
      
        const userToLogin = users[0].filter(user => user.email === loginEmail)
       
        if (userToLogin.length === 0) {
            alert("User not found. Please register if you don't have an account.")
        } else if (
            userToLogin[0].password !== loginPassword
        ) {
            alert("Incorrect password")
        } else {
            setCurrentUser(userToLogin)
        
        }
        
    }

    const openRegisterModal = () => {
        showRegisterModal(true)
    }

    if (showRegisterSuccessDialog === true) {
        getUsers()
    }


    return (
   
        <div style={{width: "60%", height: "300px"}} className="d-flex justify-content-center align-items-center">
            <form className="justify-content-center">
             <div className="form-group">
                <label htmlFor="loginEmail">Email:</label>
                <input type="text" name="loginEmail" id="loginEmail" className="form-control" value={loginEmail} onChange={onChange}></input>
             </div>
             <div className="form-group">
                 <label htmlFor="loginPassword">Password:</label>
                 <input type="password" name="loginPassword" id="loginPassword" className="form-control" value={loginPassword} onChange={onChange}></input>
             </div>
             <div className="form-group d-inline-flex">
             <button className="btn btn-primary form-control" onClick={onSubmit}>Log In</button> 
             <button type="button" className="btn btn-success form-control" style={{marginLeft: "10px"}} onClick={openRegisterModal}>Register</button>
            </div>
            <p style={{opacity: `${showRegisterSuccessDialog ? 1 : 0}`, transition: "opacity 400ms"}}>Registration successful! You can now log in.</p>
            </form>
            
        </div>
       
    
    )
}

Here's the app on Heroku. You can use johndoe@gmail.com and password 123456 as an example login to recreate the issue.

Github repo for the project.

As an aside, are there any good resources to read up on about things behaving differently in apps run locally and deployed?

users from the context is an [ { }, { } ]. so when you do users[0] it gives you an object. As the error states you can't apply filter on an object. So change your code as

const userToLogin = users.filter(user => user.email === loginEmail)

remove the [0] after users.

When you try to get the users[0] your user array returns undefined and because undefined value does not has a method called .filter you get that nasty error.

So you can so something like below to prevent that kind of behavior:

const userToLogin = users.length > 0 && users[0] !== 'undefined' && users[0].filter(user => user.email === loginEmail)

you are iterating over non-array block thats why it is giving you error of filter is not a function.

const userToLogin = users[0].filter(user => user.email === loginEmail)

remove user[0].filter instead use user.map((ele,index) => { if (ele.length > 0) { return ele[index].filter((elem) => elem.email === loginEmail)} })

if your array doesn't contain any thing it will simply return without any error.

I've managed to solve the issue. It was actually nothing to do with the code in the Login.js file and everything to do with this block of code in server:js:

if (process.env.NODE_ENV === 'production') {
  app.use(express.static('client/build'))

  app.get('*', (req, res) => {
    res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'))
  })
}

It was before all my other routes when it needed to be after them. I used a good old-fashioned console.log to look at what the getUsers() function was returning and obviously in this case it was the raw code for index.html, as it would have been for any other API request I'd tried to make. Hence all the weird letters appearing out of nowhere.

Every day's a school day, as they say. Thanks for everyone's answers anyway.

I also had that problem. Unfortunately, I put the Heroku route before the all other routes. That is the problem which I faced.

 app.use("/api/auth", require("./BACKEND/routes/auth")); app.use("/novel-book", require("./BACKEND/routes/novels")); app.use("/adventure-book", require("./BACKEND/routes/adventures")); app.use("/programming-book", require("./BACKEND/routes/programming")); app.use("/ol-book", require("./BACKEND/routes/ol")); app.use("/al-book", require("./BACKEND/routes/al")); app.use("/comment", require("./BACKEND/routes/comments")); //Error Handler (Should be the last piece of middleware) app.use(errorHandler); if(process.env.NODE_ENV === "production"){ app.use(express.static(path.join(__dirname, "/frontend/build"))); app.get("*", (req, res)=>{ res.sendFile(path.join(__dirname, "frontend", "build", "index.html")); }) }else{ app.get("/", (req,res)=>{ res.send("Api Running"); }) }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM