I am having trouble with getting my user from my database and mapping it on to the appropriate areas. Now I know the backend works because I checked postman and I am getting the user through the email but I do not really understand how to map the properties of my user after clicking submit.
What the site looks like
Frontend
ViewUser
import axios from 'axios';
import React, { useState, useEffect } from 'react'
import {useParams, useNavigate} from 'react-router-dom'
export default function ViewUser() {
const [user, setUser] = useState({
name:"",
email: "",
dob: "",
age: "",
suggestedCalories: "",
goal:"",
lifestyle:"",
weight:""
});
const onInputChange = (e) => {
setUser({ ...user, [e.target.name]: e.target.value });
};
const {email}=useParams();
useEffect(()=>{
fetch("http://localhost:8080/calorie_counter/user/${email}")
.then(res=>res.json)
.then((result)=>{
setUser(result)
})
}, [])
const onSubmit= async (e)=>{
e.preventDefault()
const result = await axios.get("http://localhost:8080/calorie_counter/user/${email}",user)
setUser(result.data)
}
return (
<div className='col-md-6 offset-md-3 border rounded p-4 mt-2 shadow'>
<form onSubmit={(e) => onSubmit(e)}>
<div className='mb-3'>
<label htmlFor='Email' className='form-label'>
E-mail
</label>
<input
type={'text'}
className='form-control'
placeholder='Enter E-mail'
onChange={(e)=>onInputChange(e)}
value={email}
name='email'
/>
<button type="submit" className='btn btn-outline-success'>Submit</button>
<button type="submit" className='btn btn-outline-danger mx-2'>Cancel</button>
</div>
</form>
<div className='card'>
<div className='card-header'>
Details of user id :
<ul className='list-group list-group-flush'>
<li className='list-group-item'>
<b>Name: </b>
{user.name}
</li>
<li className='list-group-item'>
<b>Email: </b>
{user.email}
</li>
<li className='list-group-item'>
<b>Date of Brith: </b>
{user.dob}
</li>
<li className='list-group-item'>
<b>Age: </b>
{user.age}
</li>
<li className='list-group-item'>
<b>Suggested Calories: </b>
{user.suggestedCalories}
</li>
<li className='list-group-item'>
<b>Goal: </b>
{user.goal}
</li>
<li className='list-group-item'>
<b>LifeStyle: </b>
{user.lifestyle}
</li>
</ul>
</div>
</div>
)
}
I am expecting to type an Email of a user and click the submit button. After I hit the submit button the corresponding user should appear. I tried to follow some youtube videos on useEffect and useState but I am ultimately confused.
GitHub for this project:
https://github.com/EmmanuelOlofintuyi/FullStackCalorieCounter
Related
I am trying to make a login modal popup which will show on click of a button inside of a navbar. However, I am getting below error:
TypeError: setOpenModal is not a function
Even after looking at many threads here, I am unable to understand what is causing the error in my case. Below is my code:
Navbar.js:
import React, { useState } from "react";
import { Link } from "react-router-dom";
import "./Navbar.css";
import Login from "./Login";
function Navbar() {
const [openModal, setOpenModal] = useState(false);
const showModal = () => {
setOpenModal(true);
};
return (
<nav className="navbar">
<div className="nav-div">
<Link to="/" className="nav-logo">
<i class="fas fa-hamburger"></i>Hungermania
</Link>
<div className="nav-form">
<form>
<input
className="nav-search"
type="search"
placeholder="Search for your favorite restaurant, cuisine or a dish"
></input>
<button className="btn-search">Search</button>
</form>
</div>
<ul>
<li className="nav-item">
<button className="login-btn nav-link" onClick={showModal}>
Login
</button>
{openModal && <Login setOpenModal={setOpenModal} />}
</li>
<li className="nav-item">
<button className="signup-btn nav-link">Sign Up</button>
</li>
</ul>
</div>
</nav>
);
}
export default Navbar;
Login.js:
import React from "react";
import "./Login.css";
function Login({ setOpenModal }) {
const hideModal = () => {
setOpenModal(false);
};
return (
<div className="modalBackground">
<div className="modalContainer">
<div className="titleclosebtn">
<button onClick={hideModal}>×</button>
</div>
<div className="title">
<h1>Login</h1>
</div>
<div className="body">
<form>
<label for="name">Name:</label>
<input type="text" placeholder="Full Name" required />
<br />
<br />
<label for="phone">Phone No:</label>
<input type="number" placeholder="Phone No." required />
<br />
<br />
<label for="email">Email Id:</label>
<input type="email" placeholder="Email#domain.com" required />
<br />
<br />
<div className="footer">
<button type="submit" class="btn-signup">
SIGN UP
</button>
</div>
</form>
</div>
</div>
</div>
);
}
export default Login;
There's nothing wrong with ur code, so it was prob cash or something.
restarting server should stop accusing that error.
Normally when stupid errors like this happens, i just comment that part that is accusing error, wait refresh and uncomment, that works too instead of always restarting server.
{openModal && <Login setOpenModal={setOpenModal} />}
this part of the code. You are passing down a prop named setOpenModal and you are passing down setOpenModal. You cannot pass down the setter of your state. You can either pass down variables or functions with props. So create a function, in that function you can use setOpenModal and then pass that function down like this:
const someFunction=(value)=>{
setOpenModal(value);
}
{openModal && <Login whatEverName={someFunction} />}
I was making a registration from for creating a profile. After entering the value,when I click submit I get this error
profile.js
import axios from "axios";
import { setAlert } from "./alert";
import { GET_PROFILE, PROFILE_ERROR } from "./types";
export const getCurrentProfile = () => async (dispatch) => {
try {
const res = await axios.get("/api/profile/me");
dispatch({
type: GET_PROFILE,
payload: res.data,
});
} catch (error) {
dispatch({
type: PROFILE_ERROR,
payload: {
msg: error.response.statusText,
status: error.response.status,
},
});
}
};
//Create or Update profile
export const createProfile =
(formData, history, edit = false) =>
async (dispatch) => {
try {
const config = {
headers: {
"Content=Type": "application/json",
},
};
const res = await axios.post("/api/profile", formData, config);
dispatch({
type: GET_PROFILE,
payload: res.data,
});
dispatch(setAlert(edit ? "Profile Updated" : "Profile Created"));
if (!edit) {
history.push("/dashboard");
}
} catch (error) {
const errors = error.response.data.errors;
if (errors) {
errors.forEach((error) => dispatch(setAlert(error.msg, "danger")));
}
dispatch({
type: PROFILE_ERROR,
payload: {
msg: error.response.statusText,
status: error.response.status,
},
});
}
};
CreateProfile.js
import React, { Fragment, useState } from "react";
import { Link, withRouter } from "react-router-dom";
import { createProfile } from "../../actions/profile";
import { connect } from "react-redux";
import PropTypes from "prop-types";
const CreateProfile = ({ createProfile, history }) => {
const [formData, setFormData] = useState({
status: "",
company: "",
bio: "",
website: "",
location: "",
skills: "",
github_username: "",
twitter: "",
facebook: "",
linkedin: "",
});
const [displaySocialInputs, toggleSocialInputs] = useState(false);
const {
status,
company,
bio,
website,
location,
skills,
github_username,
twitter,
facebook,
linkedin,
} = formData;
const onChange = (e) =>
setFormData({ ...formData, [e.target.name]: e.target.value });
const onSubmit = (e) => {
e.preventDefault();
createProfile(formData, history);
};
return (
<Fragment>
<h1 className='large text-primary'>Create Your Profile</h1>
<p className='lead'>
<i className='fas fa-user'></i> Let's get some information to make your
profile stand out
</p>
<small>* = required field</small>
<form className='form' onSubmit={(e) => onSubmit(e)}>
<div className='form-group'>
<select name='status' value={status} onChange={(e) => onChange(e)}>
<option value='0'>* Select Professional Status</option>
<option value='Developer'>Developer</option>
<option value='Junior Developer'>Junior Developer</option>
<option value='Senior Developer'>Senior Developer</option>
<option value='Manager'>Manager</option>
<option value='Student or Learning'>Student or Learning</option>
<option value='Instructor'>Instructor or Teacher</option>
<option value='Intern'>Intern</option>
<option value='Other'>Other</option>
</select>
<small className='form-text'>
Give us an idea of where you are at in your career
</small>
</div>
<div className='form-group'>
<input
type='text'
placeholder='Company'
name='company'
value={company}
onChange={(e) => onChange(e)}
/>
<small className='form-text'>
Could be your own company or one you work for
</small>
</div>
<div className='form-group'>
<input
type='text'
placeholder='Website'
name='website'
value={website}
onChange={(e) => onChange(e)}
/>
<small className='form-text'>
Could be your own or a company website
</small>
</div>
<div className='form-group'>
<input
type='text'
placeholder='Location'
name='location'
value={location}
onChange={(e) => onChange(e)}
/>
<small className='form-text'>
City & state suggested (eg. Boston, MA)
</small>
</div>
<div className='form-group'>
<input
type='text'
placeholder='* Skills'
name='skills'
value={skills}
onChange={(e) => onChange(e)}
/>
<small className='form-text'>
Please use comma separated values (eg. HTML,CSS,JavaScript,PHP)
</small>
</div>
<div className='form-group'>
<input
type='text'
placeholder='Github Username'
name='githubusername'
value={github_username}
onChange={(e) => onChange(e)}
/>
<small className='form-text'>
If you want your latest repos and a Github link, include your
username
</small>
</div>
<div className='form-group'>
<textarea
placeholder='A short bio of yourself'
name='bio'
value={bio}
onChange={(e) => onChange(e)}
></textarea>
<small className='form-text'>Tell us a little about yourself</small>
</div>
<div className='my-2'>
<button
onClick={() => toggleSocialInputs(!displaySocialInputs)}
type='button'
className='btn btn-light'
>
Add Social Network Links
</button>
<span>Optional</span>
</div>
{displaySocialInputs && (
<Fragment>
<div className='form-group social-input'>
<i className='fab fa-twitter fa-2x'></i>
<input
type='text'
placeholder='Twitter URL'
name='twitter'
value={twitter}
onChange={(e) => onChange(e)}
/>
</div>
<div className='form-group social-input'>
<i className='fab fa-facebook fa-2x'></i>
<input
type='text'
placeholder='Facebook URL'
name='facebook'
value={facebook}
onChange={(e) => onChange(e)}
/>
</div>
<div className='form-group social-input'>
<i className='fab fa-linkedin fa-2x'></i>
<input
type='text'
placeholder='Linkedin URL'
name='linkedin'
value={linkedin}
onChange={(e) => onChange(e)}
/>
</div>
</Fragment>
)}
<input type='submit' className='btn btn-primary my-1' />
<a className='btn btn-light my-1' href='dashboard.html'>
Go Back
</a>
</form>
</Fragment>
);
};
CreateProfile.propTypes = {
createProfile: PropTypes.func.isRequired,
};
export default connect(null, { createProfile })(withRouter(CreateProfile));
Everything before this was working fine.I was able to log in,check if the user has a profile or not,but this error: Unhandled Rejection (TypeError): Cannot read property 'data' of undefined I've checked many sources but I can't find what is wrong.
My sand box link for the project
I have solved the problem.
So the first issue I came across is that I can't enter a Github user name when creating a profile.
Which is because in my CreateProfile.js I have github_username in state, but the input name is name="githubusername" And I am updating state using the name as the key in state, so the value never changes.
So change the name to match
name="github_username"
After that I can enter a Github user name and I tried to submit the form, but it still didn't solve the issue completely.
The error is actually coming from my config object in actions/profile.js createProfile function because I have..
"Content=Type": "application/json",
Which should be
Content-Type not Content=Type
I want to change the user value to true when a user clicks a login button in my login page. I'm a beginner level web dev student and I am still learning how to use useState in React. I am sorry for this dumb question but please help! Thank you so much!!!!
TopBar.jsx
import { Link } from 'react-router-dom';
import './topbar.css';
export default function topbar() {
const user = false;
return (
<div className='top'>
<div className='topLeft'>
<i className='topIcon fab fa-facebook-square'></i>
<i className='topIcon fab fa-twitter-square'></i>
<i className='topIcon fab fa-pinterest-square'></i>
<i className='topIcon fab fa-instagram-square'></i>
</div>
<div className='topCenter'>
<ul className='topList'>
<li className='topListItem'>
<Link className='link' to ='/'>HOME</Link>
</li>
<li className='topListItem'><Link className='link' to ='/'>ABOUT</Link></li>
<li className='topListItem'><Link className='link' to ='/'>CONTACT</Link></li>
<li className='topListItem'><Link className='link' to ='/write'>WRITE</Link></li>
<li className='topListItem'>{user && 'LOGOUT'}</li>
</ul>
</div>
<div className='topRight'>
{
user ? (
<Link className='link' to ='/settings'>
<img
className='topImg'
src="https://organicthemes.com/demo/profile/files/2018/05/profile-pic.jpg"
alt=""
/>
</Link>
) : (
<ul className='topList'>
<li className='topListItem'>
<Link className='link' to ='/login'>LOGIN</Link>
</li>
<li className='topListItem'>
<Link className='link' to ='/register'>REGISTER</Link>
</li>
</ul>
)
}
<i className='topSearchIcon fas fa-search'></i>
</div>
</div>
);
}
Login.jsx
import { Link } from 'react-router-dom';
import './login.css'
export default function Login() {
return (
<div className='login'>
<span className="LoginTitle">Login</span>
<form className="loginForm">
<label>Email</label>
<input type="text" className='loginInput' placeholder='Enter your email...' />
<label>Password</label>
<input type="password" className='loginInput' placeholder='Enter your password...' />
<button className="loginButton">Login</button>
</form>
<button className="loginRegisterButton">
<Link className='link' to='/register'>Register</Link>
</button>
</div>
);
}
Thank you for helping!
I have know idea why are you solving this way. But to be reactive you should store that user in state.
E.g
import {useState} from 'react';
const [user, setUser] = useState(false);
return (
<button onClick={() => setUser(true)}>Click me!</button>
)
Do you write your own server script? You need to send a HTTPS POST request to the server and validate the login data. Look into React-Router, Express, or Next.js to learn about server-side routing.
Here's a beginner friendly article about POST requests
I'm developing a Next.JS application that lists some Github users and when I click on a especific user box, their box should toggle using Reactstrap's Collapse. But all boxes toggle at once, independent of the clicked user. I've tried to separate their onClick events, without success.
Here is my frontend code:
import React, { useEffect, useState } from "react"
import { Collapse, CardBody, Card } from 'reactstrap'
export default function Users() {
const [isOpen, setIsOpen] = useState(false);
const toggle = (e) => {
setIsOpen(!isOpen)
}
return (
<ul>
{users.map(user => (
<li>
<div className="user-space">
<div className="closed-user">
<img onClick={toggle} src={user.avatar_url} alt={user.login} id={user.login} />
<h3 onClick={toggle} className="nickName" id={user.login}>{user.login}</h3>
</div>
<Collapse isOpen={isOpen}>
<Card className="accordion">
<CardBody className="accordion-text">
<label>User Name: {user.name}</label>
<label>User Bio: {user.bio}</label>
<label>User Location: {user.location}</label>
<label>User Blog: {user.blog} </label>
<label>Number of followers: {user.followers}</label>
<label>Number of public repositories: {user.public_repos}</label>
</CardBody>
</Card>
</Collapse>
</div>
</li>
))}
</ul>
)
}
You can apply your isOpen if you expand all user cards. If you want expand specified user card. You should have state for which user is expanding:
Here just my example. You can use use.id instead of state index.
function Users() {
const [index, setIndex] = useState(false);
const toggle = (idx) => {
setIndex(index === idx ? null : idx);
}
return (
<ul>
{users.map((user, idx) => (
<li id={idx}>
<div className="user-space">
<div className="closed-user">
<img onClick={() => toggle(idx)} src={user.avatar_url} alt={user.login} id={user.login} />
<h3 onClick={() => toggle(idx)} className="nickName" id={user.login}>{user.login}</h3>
</div>
<Collapse isOpen={idx === index}>
<Card className="accordion">
<CardBody className="accordion-text">
<label>User Name: {user.name}</label>
<label>User Bio: {user.bio}</label>
<label>User Location: {user.location}</label>
<label>User Blog: {user.blog} </label>
<label>Number of followers: {user.followers}</label>
<label>Number of public repositories: {user.public_repos}</label>
</CardBody>
</Card>
</Collapse>
</div>
</li>
))}
</ul>
)
}
When clicked close button code detects in the console that the component want's to be hidden but when I want to open the modal window by clicking the Logic or Signup button in navigation.js file those buttons don't detect any activity to the console.
This where I'm got the tutorial on how to do the modal widow but tried to work out for my need's --> https://alligator.io/react/modal-component/
Modal Window Component:
import React from 'react';
const Modal = ({ show, children }) => {
const showHideClassName = show ? 'modal display-block' : 'modal display-none';
return (
<div className={showHideClassName}>
<section className='modal-main'>
{children}
</section>
</div>
);
};
class App extends React.Component {
state = { show: false }
showSignup = () => {
this.setState({ show: true });
console.log('I was triggered during componentDidMount')
}
showLogin = () => {
this.setState({ show: true });
console.log('Fuck this not show the login form')
}
hideModal = () => {
this.setState({ show: false });
console.log('Yeah its hide the login and signup form')
}
render() {
return (
<div>
<Modal show={this.state.show} handleclose={this.hideModal} >
<div className="blkOverlay">
{/* This is Login Form to log in to your profile */ }
<div className="formContent modal-main">
<button className="closebtn" onClick={this.hideModal}>Close </button>
<h2>Welcome Back <span>Brandon!</span></h2>
<form data-show={this.state.show.toString()}>
<input type="text" name="email" placeholder="Email Address" />
<input name="password" type="text" placeholder="Password" />
<div className="passContent">
<div className="checkingPass">
<input className="inline" type="checkbox" name="check" value="Remember Password"/>
<span className="inline">Remember Password</span>
</div>
<p className="passFont">Forgot Password</p>
</div>
<input className="formmbtn" type="button" name="button" value="Login"/>
<div className="social-media-button">
<input className="clearbtn" type="button" name="button" value="Sign in with Facebook"/>
<div className="divider"/>
<input className="clearbtn" type="button" name="button" value="Sign in with Facebook"/>
</div>
<p className="passFont">Don't have an account? <span>Sign up</span></p>
</form>
</div>
{/* This is Sign up to create a account */}
</div>
</Modal>
</div>
)
}
}
export default App;
Navigation Component (Where the buttons are at to call the modal window to appear on click)
import React from 'react';
import { BrowserRouter as Router, Link } from 'react-router-dom';
import Dropdown from "../components//pages/dropdowns/dropdowns.js";
import "../components/pages/SignupModal/signupmodal.js";
import hamburger from "../images/menu.svg";
class Navigation extends React.Component {
constructor(props) {
super(props);
this.state = {
isExpanded: false
};
}
handleToggle(e) {
e.preventDefault();
this.setState(prevState => ({
isExpanded: !prevState.isExpanded, // negate the previous expanded state
}));
}
render() {
const { isExpanded } = this.state;
return (
<Router>
<div className="NavbarContainer">
<div className="mobilecontainer LeftNav">
<h2 className="BrandName LeftNav mobileboxmenu inline FarRight">Kommonplaces</h2>
<div className="hamburger inlinev" >
<img
onClick={e => this.handleToggle(e)}
alt="menubtn"
src={hamburger}
/>
</div>
</div>
<ul className={`NavBar collapsed ${isExpanded ? "is-expanded" : ""}`}>
<Dropdown/>
<li className="RightNav"><Link to="/">Host Your Space</Link></li>
<li className="RightNav"><Link to="/">About Us</Link></li>
<li className="RightNav"><Link to="/">Contact Us</Link></li>
<div className="btnflexright">
<button className="RightNav"><Link onClick={ this.showSignup } to="/">Sign Up</Link></button>
<button className="RightNav"><Link onClick={ this.showLogin } to="/">Login</Link></button>
</div>
</ul>
</div>
</Router>
);
}
}
export default Navigation;
Any, helpful tips and advice would help, please.
That's because you placed the onClick event in the Link rather than on the button component. Change to the code below:
<div className="btnflexright">
<button className="RightNav" onClick={ this.showSignup }>
<Link to="/">Sign Up</Link>
</button>
<button className="RightNav" onClick={ this.showLogin }>
<Link to="/">Login</Link>
</button>
</div>