I'm trying to make a sport/tinder like app for a school project from a friend of mine. It came together well on my localhost, but for him it was a requirement to host it online. Not really a professional in hosting, but I was a bit familiar with Heroku. I used a client and a server side for my application, so I build the client side and put it into the server side folder. This server side is hosted on the Heroku page. But whenever I try to login, it won't work and I get this error message in my console.
TypeError: Cannot read properties of undefined (reading 'map')
I know there are a lot of other people with the same issue. I tried many solutions and I think something might be wrong with my code. I'm very new to ReactJS, that's why I used a tutorial for making this application. And I'm more like a Data Scientist then a Software Engineer, but I'm always eager to learn. That's why I took the oppurtunity to learn this new 'language'. So I might be wrong when it comes to the problem.
The error says it is caused by this line of code.
const matchedUserIds = user?.matches.map(({user_id}) => user_id).concat(userId)
This is the whole Dashboard file I used for making this page. I'm using a MongoDB for the storage of my users.
import TinderCard from 'react-tinder-card';
import {useEffect, useState} from 'react';
import {useCookies} from 'react-cookie';
import ChatContainer from '../components/ChatContainer'
import axios from "axios";
const Dashboard = () => {
const [user, setUser] = useState(null)
const [genderedUsers, setGenderedUsers] = useState(null)
const [cookies, setCookie, removeCookie] = useCookies(['user'])
const [lastDirection, setLastDirection] = useState()
const userId = cookies.UserId
const getUser = async () => {
try {
const response = await axios.get('https://[app].herokuapp.com/user', {
params: {userId}
})
setUser(response.data)
} catch (error) {
console.log(error)
}
}
const getGenderedUsers = async () => {
try {
const response = await axios.get('https://[app].herokuapp.com/gendered-users', {
params: {gender: user?.gender_interest}
})
setGenderedUsers(response.data)
} catch (error) {
console.log(error)
}
}
useEffect(() => {
getUser()
}, [])
useEffect(() => {
if (user) {
getGenderedUsers()
}
}, [user])
const updateMatches = async (matchedUserId) => {
try {
await axios.put('https://[app].herokuapp.com/addmatch', {
userId,
matchedUserId
})
getUser()
} catch (error) {
console.log(error)
}
}
const swiped = (direction, swipedUserId) => {
console.log(direction, swipedUserId)
if (direction === 'right') {
updateMatches(swipedUserId)
}
setLastDirection(direction)
}
const outOfFrame = (name) => {
console.log(name + ' left the screen!')
}
const matchedUserIds = user?.matches.map(({user_id}) => user_id).concat(userId)
const filteredGenderedUsers = genderedUsers?.filter(
genderedUser => !matchedUserIds.includes(genderedUser.user_id)
)
return (<>
{user && <div className="dashboard">
<ChatContainer user={user}/>
<div className="swipe-container">
<div className="card-container">
{filteredGenderedUsers?.map((genderedUser) =>
<TinderCard
className='swipe'
key={genderedUser.user_id}
onSwipe={(dir) => swiped(dir, genderedUser.user_id)}
onCardLeftScreen={() => outOfFrame(genderedUser.first_name)}>
<div style={{backgroundImage: 'url(' + genderedUser.url + ')'}} className='card'>
<h3>{'Name: ' + genderedUser.first_name} <br/> {'Sport: ' + genderedUser.about}</h3>
</div>
</TinderCard>)}
<div className="swipe-info">
{lastDirection ? <p>You swiped {lastDirection}</p> : <p/>}
</div>
</div>
</div>
</div>}
</>)
}
export default Dashboard
Any help is welcome. If you need more code examples, please reply ;)
EDIT
My index.js file from my server, GET request for my user
app.get('/user', async (req, res) => {
const client = new MongoClient(uri)
const userId = req.query.userId
try {
await client.connect()
const database = client.db('app-data')
const users = database.collection('users')
const query = {user_id: userId}
const user = await users.findOne(query)
res.send(user)
} finally {
await client.close()
}
})
My index.js file from my server, GET request for my gendered-users
app.get('/gendered-users', async (req, res) => {
const client = new MongoClient(uri)
const gender = req.query.gender
try {
await client.connect()
const database = client.db('app-data')
const users = database.collection('users')
const query = {gender_identity: {$eq: gender}}
const foundUsers = await users.find(query).toArray()
res.send(foundUsers)
} finally {
await client.close()
}
})
A picture from my MongoDB users (Dummy data)
EDIT 2
The line of code that causes the new error
const matchedUserIds = matches.map(({user_id}) => user_id)
My MatchesDisplay file.
import axios from "axios";
import {useEffect, useState} from 'react';
import { useCookies } from "react-cookie";
const MatchesDisplay = ({matches, setClickedUser}) => {
const [matchedProfiles, setMatchedProfiles] = useState(null)
const [cookies, setCookie, removeCookie] = useCookies(null)
const [matched, setMatched] = useState(null)
const matchedUserIds = matches.map(({user_id}) => user_id)
const userId = cookies.UserId
const getMatches = async () => {
try {
const response = await axios.get('https://[app].herokuapp.com/users', {
params: {userIds: JSON.stringify(matched())}
})
setMatchedProfiles(response.data)
} catch (error) {
console.log(error)
}
}
useEffect(() => {
getMatches()
}, [matches])
const filteredMatchedProfiles = matchedProfiles?.filter(
(matchedProfile) =>
matchedProfile.matches.filter((profile) => profile.user_id === userId).length > 0
)
return (
<div className="matches-display">
{filteredMatchedProfiles?.map((match) => (
<div key={match.user_id} className="match-card" onClick={() => setClickedUser(match)}>
<div className="img-container">
<img src={match?.url} alt={match?.first_name + 'profile'}/>
</div>
<h3>{match?.first_name}</h3>
</div>
))}
</div>
)
}
export default MatchesDisplay