React-Bootstrap dynamic Image rendering - image

I am trying to display profile pic by calling the path and file name from database
Profile Image is not loading is it the path?
using json server local test.
Image is saved in folder ../src/image/
json data
image: "..image/pic.jpg"
import { Card, ListGroup } from "react-bootstrap";
import { useParams, useHistory } from "react-router-dom";
import useFetch from "./useFetch";
const MemberProfile = () => {
const { id } = useParams();
const {
data: member,
error,
isLoading,
} = useFetch("http://192.168.0.23:8000/members/" + id);
const history = useHistory();
const handleClick = () => {
fetch("http://192.168.0.23:8000/members/" + member.id, {
method: "DELETE",
}).then(() => {
history.push("/");
});
};
return (
<div className="memberProfile">
{isLoading && <div>Loading...</div>}
{error && <div>{error}</div>}
{member && (
<Card style={{}}>
<Card.Img variant="top" src={member.image} />
<Card.Body>
<Card.Title>
<h2>
<strong>
Profile - {member.name} {id}
</strong>
</h2>
</Card.Title>
<Card.Text>
<pre className="acordnBody">
Gender : {member.gender} <hr />
Phone : {member.tel} <hr />
E-mail : {member.email} <hr />
Address : {member.address}
</pre>
</Card.Text>
</Card.Body>
</Card>
)}
</div>
);
};
export default MemberProfile;

Related

How can I resolve this promise from external function in React JSX?

I need some help understanding what and why this does not work when in React JSX, but does in standard JS.
First off, what is it called when you reference a var as a function?
var promiseResolve;
promiseResolve();
And second why does React return: "Uncaught TypeError: promiseResolve is not a function" when trying to call it?
I know this sounds like a intro question, but I've been doing pretty complex JS and now React web builds for five years now, and I embarrassingly don't know what it means to call an undefined function like that.
This all fits into a bigger question of trying to resolve a promise from an await in an external function via a modal, but without trying to go into detail, if the below would work in JSX, it would solve my problems.
var promiseResolve, promiseReject;
var promise = new Promise(function(resolve, reject){
promiseResolve = resolve;
promiseReject = reject;
});
promiseResolve();
For more context, I'm trying to get this to work (EDIT: request to show full code after this blurb. Everything else works, it's only recently I was asked to add a process to warn if an email was already sent):
let promiseResolve, promiseReject;
const resendAttempt = () => new Promise((resolve,reject) => {
promiseResolve = resolve;
promiseReject = reject;
});
const resolvePromise = () => {
promiseResolve();
}
return (
<Modal... <button onclick={resolvePromise} ... /> ... />
<Form onSubmit={async (values ...
await resendAttempt();
)}
/>
)
FULL CODE, look for comments on where issue is:
import React, { useState } from 'react';
import { Formik, Form, useField, FieldArray, Field } from 'formik';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Button from 'components/Elements/Button';
import H3 from 'components/Elements/H2';
import Modal from 'react-bootstrap/Modal';
import BootstrapButton from 'react-bootstrap/Button';
import Wrapper from './Wrapper';
const TeamRecruitmentForm = props => {
const [showForm, setShowForm] = useState(true);
const [customFormError, setCustomFormError] = useState(false);
const [customFormSuccess, setCustomFormSuccess] = useState(false);
const [recruitRow, setRecruitRow] = useState({
recruitFirstName: '',
recruitLastName: '',
recruitEmail: ''
});
const captFirstName = props.userData.name ? props.userData.name.first : '';
const captLastName = props.userData.name ? props.userData.name.last : '';
const cityName = props.customGreetingFields.eventCity ? props.customGreetingFields.eventCity : '';
let messageSubject = `Join ${captFirstName} ${captLastName}\'s Leaders for Life Team`;
let promiseResolve, promiseReject;
const resendAttempt = () => new Promise((resolve,reject) => {
promiseResolve = resolve;
promiseReject = reject;
});
// this is called with a modaal button click
const resolvePromise = () => {
promiseResolve(); // JS errror, console says it is not a function
}
const [showTeammember, setShowTeammember] = useState(false);
const [showResend, setShowResend] = useState(false);
const handleClose = () => {
console.log('handleClose');
setShowTeammember(false);
setShowResend(false);
};
const handleShow = (modal) => {
console.log('handleShow');
if (modal == 'teammember') {
setShowTeammember(true);
} else if (modal == 'resend') {
setShowResend(true);
}
};
function validateEmail(value,x) {
let error;
const filterTeamRoster = props.teamRosterActivity.filter(user => {
return user.email == value;
});
if (!value) {
error = 'Required';
} else if (!/^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)) {
error = 'Invalid email address';
}
else if (filterTeamRoster.length > 0) {
handleShow('teammember');
error = 'Current Teammember';
}
return error;
}
function validateFirstName(value) {
let error;
if (!value) {
error = 'Required';
}
return error;
}
function validateLastName(value) {
let error;
if (!value) {
error = 'Required';
}
return error;
}
return (
<>
<Modal
show={showTeammember}
id={props.id}
size={props.size}
onHide={handleClose}
className={`mx-auto ${props.modalClass}`}
centered
>
<Modal.Header closeButton closeLabel="Back" className="bg-primary py-1">
<BootstrapButton
variant="link"
onClick={handleClose}
className={`text-white btn-modal-back btn-back-${props.modalClass}`}
>
<span className="fas fa-caret-left" alt="" />
Back
</BootstrapButton>
</Modal.Header>
<Modal.Body>
<H3>Current Teammember</H3>
<p>The person associated with the email address has already joined your team</p>
<Button variant="primary" className="btn-block" onClick={handleClose}>
OK
</Button>
</Modal.Body>
</Modal>
<Modal
show={showResend}
id={props.id}
size={props.size}
onHide={handleClose}
className={`mx-auto ${props.modalClass}`}
centered
>
<Modal.Header closeButton closeLabel="Back" className="bg-primary py-1">
<BootstrapButton
variant="link"
onClick={handleClose}
className={`text-white btn-modal-back btn-back-${props.modalClass}`}
>
<span className="fas fa-caret-left" alt="" />
Back
</BootstrapButton>
</Modal.Header>
<Modal.Body>
<H3>You already sent an invite to this email address.</H3>
<p>Would you like to send it again"</p>
{/* This is the button I'm using to test allowing the dupe email
form to be send */}
<Button variant="primary" className="btn-block" onClick={resolvePromise}>
OK
</Button>
</Modal.Body>
</Modal>
<Wrapper key={props.formNumber} {...props}>
{customFormError === false && customFormSuccess === true ? (
<div className="my-1">
<Row>
<Col xs={6} md={3}
className="pr-1 pr-md-2 pb-2 email-sent-container"><span className="email-sent">{recruitRow.recruitFirstName}</span></Col>
<Col xs={6} md={3}
className="pr-1 pr-md-2 pb-2 email-sent-container"><span className="email-sent">{recruitRow.recruitLastName}</span></Col>
<Col md={4}
className="pl-md-2 pb-2 email-sent-container"><span className="email-sent">{recruitRow.recruitEmail}</span></Col>
<Col xs={6} md={2}
className="pb-2">
<Button variant="primary" type="submit" disabled>
Sent!
</Button>
</Col>
</Row>
</div>
) :
(<Formik
{...props}
initialValues={{ recruits: [{firstName: "", lastName: "", emailAddress: ""}] }}
validateOnChange={false}
validateOnBlur={false}
onSubmit={ async (values, { setSubmitting, setFieldError, setStatus }) => {
// this is the array it checks in order to kick bcak option to continue
// or cancel the submissions process
const filterSentMessages = props.sentMessages.filter(user => {
return user.recipients == values['emailAddress'+props.formNumber];
});
console.log("before sleep");
if (filterSentMessages.length > 0) {
handleShow('resend');
}
// this works, but the button click in the modal
// to resolve this is the issue where I get undefined
await resendAttempt();
let recipient = `${values['firstName'+props.formNumber]} ${values['lastName'+props.formNumber]} <${encodeURIComponent(values['emailAddress'+props.formNumber])}>,`;
console.info('recipient:', recipient);
let messageBody = `<p>Dear ${values['firstName'+props.formNumber]},</p><p>... message content ...</p><p>Thank you in advance for your commitment to making an impact!</p><p>${captFirstName}!</p>`
messageBody = encodeURIComponent(messageBody);
let x = 2; // this is here to just stop sending so many test emails
if( x == 1 ) { // this is here to just stop sending so many test emails
try {
props.sendMessage(
localStorage.getItem('frId'),
messageSubject,
messageBody,
recipient,
props.eventConfig.defaultStationeryId,
);
} catch (error) {
console.log('form submit error:', error);
setShowForm(!showForm);
setSubmitting(false);
}
}
setRecruitRow({...recruitRow, recruitFirstName: values['firstName'+props.formNumber], recruitLastName: values['lastName'+props.formNumber], recruitEmail: values['emailAddress'+props.formNumber]})
setCustomFormError(false);
setCustomFormSuccess(true);
setSubmitting(false);
}}
render={({ values,errors }) => (
<Form className="my-1" id={`recruitForm${props.formNumber}`}>
<FieldArray
name="recruits"
render={(arrayHelpers) => (
<>
{(values.recruits && values.recruits.length > 0) && (
values.recruits.map((recruit, index) => (
<Row key={props.formNumber}>
<Col xs={6} md={3}
className="pr-1 pr-md-2 pb-2"
>
<label htmlFor={`firstName${props.formNumber}`} className="sr-only">
First Name
</label>
<Field
className="form-control"
type="text"
name={`firstName${props.formNumber}`}
placeholder="First Name"
id={`firstName${props.formNumber}`}
validate={validateFirstName}
/>
{errors['firstName'+props.formNumber] && <div className="text-danger" role="alert">{errors['firstName'+props.formNumber]}</div>}
</Col>
<Col xs={6} md={3}
className="pl-1 px-md-2 pb-2"
>
<label htmlFor={`lastName${props.formNumber}`} className="sr-only">
Last Name
</label>
<Field
className="form-control"
type="text"
name={`lastName${props.formNumber}`}
placeholder="Last Name"
id={`lastName${props.formNumber}`}
validate={validateLastName}
/>
{errors['lastName'+props.formNumber] && <div className="text-danger" role="alert">{errors['lastName'+props.formNumber]}</div>}
</Col>
<Col md={4}
className="pl-md-2 pb-2"
>
<label htmlFor={`emailAddress${props.formNumber}`} className="sr-only">
Email Address
</label>
<Field
className="form-control"
type="text"
name={`emailAddress${props.formNumber}`}
placeholder="Email Address"
id={`emailAddress${props.formNumber}`}
validate={validateEmail}
/>
{errors['emailAddress'+props.formNumber] && <div className="text-danger" role="alert">{errors['emailAddress'+props.formNumber]}</div>}
</Col>
<Col xs={6} md={2}
className="pb-2"
>
<Button variant="primary" type="submit">
Send
</Button>
</Col>
</Row>
))
)}
</>
)}
/>
</Form>
)}
/>
)}
</Wrapper>
</>
);
};
export default TeamRecruitmentForm;

Submission of Form Data via Nextjs and Graphql Apollo

I am trying to do a POST method using ApolloGraphql Mutation into my local postgres database. I am able to query and my api works when I am adding a new item via the Apollo Graphql Client, but am trying to figure out a way to post via a form.
import type { NextPage } from 'next'
import Head from 'next/head'
import {Card} from "../components/Card"
//import {products} from "../data/products";
import {gql, useQuery, useMutation} from "#apollo/client"
import { useState } from 'react';
const AllProductQuery = gql`
query Product_Query {
products {
title
description
}
}
`;
const AddProducts = gql`
mutation Add_Product($title: String!
$description: String!
) {
product(description: $description, title: $title) {
id
description
title
}
}
`;
const Home: NextPage = () => {
const {data, error, loading} = useQuery(AllProductQuery);
const [title, setTitle] = useState("")
const [description, setDescription] = useState("")
const [createPost] = useMutation(AddProducts, {
variables: {
title,
description
}
});
if (loading) {return <p>Loading...</p>}
if(error) {return <p>{error.message}</p>}
return (
<div >
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<div className='container mx-auto my-20 px-5 '>
{data.products.map((product: any) => (
<Card key={product.id} title={product.title} description={product.description} />
))}
</div>
<form className='flex flex-col p-2' onSubmit={e => {
e.preventDefault(); createPost();
}}>
<input placeholder="Title" type='text' value={title}onChange={(e) => {setTitle(e.target.value);}} required/>
<input placeholder="Description" type='text' value={description} onChange={(e) => {setDescription(e.target.value);}} required/>
<button type="submit" className='bg-blue-500 text-white rounded-lg'>Submit</button>
</form>
</div>
)
}
export default Home
I am currently creating a [createPost] with a useMutation function and putting my variables as title and description. In the form I then apply that method. Any help would be great!

Form is not rendered

I'm making a todo app and using useState to pass value to the form then submit the todo but for some reasons my todo form is not render and i don't know what is missing in my codes, please help me to check! Thank you so much!
import React, { useState } from "react";
function Todo({ todo, index }) {
console.log("hiiii");
return (
<div>
<p>{todo.text}</p>
</div>
);
}
function todoForm(addTodo) {
const [value, setValue] = useState("");
handleSubmit = (e) => {
e.preventDefault();
if (!value) return;
addTodo(value);
setValue("");
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="add new todo"
value={value}
onChange={(e) => {
setValue(e.target.value);
}}
/>
</form>
</div>
);
}
function App() {
const [todos, setTodos] = useState([
{
text: "eat lunch",
isCompleted: false
},
{
text: "do homework",
isCompleted: false
},
{
text: "go to school",
isCompleted: false
}
]);
addTodo = (text) => {
console.log("hey");
const newTodos = [...todos, { text }];
setTodos(newTodos);
};
return (
<div>
<div>
{todos.map((todo, index) => {
return <Todo key={index} index={index} todo={todo} />;
})}
</div>
<div>
<todoForm addTodo={addTodo} />
</div>
</div>
);
}
export default App;
Link sandbox: https://codesandbox.io/s/serverless-bash-ef4hk?file=/src/App.js
JSX tags must be uppercased in order to be properly parsed by the compiler as a React component.
Instead of todoForm, use TodoForm.
Capitalized types indicate that the JSX tag is referring to a React component. These tags get compiled into a direct reference to the named variable, so if you use the JSX expression, Foo must be in scope.
From: https://reactjs.org/docs/jsx-in-depth.html#specifying-the-react-element-type
Also, you need to destructure props inside TodoForm in order to gain access to addTodo:
// Bad
function TodoForm(addTodo) {...}
// Good
function TodoForm({addTodo}) {...}
You should also assign you handlers to consts:
// Bad
addTodo = (text) => {...};
// Good
const addTodo = (text) => {...};
your problem is solved it
APP.JS
import React, { useState } from "react";
function Todo({ todo, index }) {
console.log("hiiii");
return (
<div>
<p>{todo.text}</p>
</div>
);
}
function todoForm(addTodo) {
const [value, setValue] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
if (!value) return;
addTodo(value);
setValue("");
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="add new todo"
value={value}
onChange={(e) => {
setValue(e.target.value);
}}
/>
</form>
</div>
);
}
function App() {
const [todos, setTodos] = useState([
{
text: "eat lunch",
isCompleted: false
},
{
text: "do homework",
isCompleted: false
},
{
text: "go to school",
isCompleted: false
}
]);
const addTodo = (text) => {
console.log("hey");
const newTodos = [...todos, { text }];
setTodos(newTodos);
};
return (
<div>
<div>
{todos.map((todo, index) => {
return <Todo key={index} index={index} todo={todo} />;
})}
</div>
<div>
{todoForm(addTodo)}
</div>
</div>
);
}
export default App;

Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component

Homepage.js
import React, { Component } from 'react';
import { Route, Redirect, withRouter } from 'react-router-dom';
import $ from 'jquery';
import { css } from 'glamor';
import { ToastContainer } from 'react-toastify';
import toast from '../toast';
import { BarLoader } from 'react-spinners';
// ---------------- Custom components
import Header from '../Header/Header';
import Footer from '../Footer/Footer';
import RelayAnimation from '../RelayAnimation/RelayAnimation';
import UserLoginForm from '../UserLoginForm/UserLoginForm';
import UserSignUpForm from '../UserSignUpForm/UserSignUpForm';
import PassResetReqForm from '../PassResetReqForm/PassResetReqForm';
import PassResetForm from '../PassResetForm/PassResetForm';
import './HomePage.css';
// --------- Message for Network Error
const Msg = () => (
<div>
Error please, try again later <br /> or reload the Page.
</div>
);
class HomePage extends Component {
constructor(props) {
super(props);
this.state = {
loading: false
};
this.toggleLoader = this.toggleLoader.bind(this);
this.notifySuccess = this.notifySuccess.bind(this);
this.notifyError = this.notifyError.bind(this);
}
notifySuccess(msg) {
toast.success(msg);
}
notifyError(msg) {
toast.error(msg);
}
// --------- Toast Notifications ---------------
// notify = (status) => {
// // --------- Server Issue Toaster
// if (status === 'Bad Gateway') {
// toast.error(<Msg />, {
// className: {
// color: '#fff',
// minHeight: '60px',
// borderRadius: '8px',
// boxShadow: '2px 2px 20px 2px rgba(0,0,0,0.3)'
// }
// });
// }
// }
toggleLoader() {
this.setState({
loading: !this.state.loading
});
}
isAuthenticated() {
const token = localStorage.getItem('authToken');
if (token) {
return true;
}
}
componentDidMount() {
const currentLocationPath = this.props.location.pathname;
const urlForEmailVerification = currentLocationPath.includes('/api/v1/verifyEmailUser/');
if (urlForEmailVerification) {
const { token } = this.props.match.params; // token value from url params passed by <Route/>
if (token) {
const url = `/api/v1/verifyEmailUser/${token}`;
// api call to make the user's account verified in db based on token in url
$.ajax({
url: url,
dataType: 'json',
type: 'GET',
success: function (res) {
console.log(res);
this.notifySuccess('emailVerified');
this.props.history.push('/');
}.bind(this),
error: function (xhr, status, err) {
console.error(url, status, err.toString());
}.bind(this)
});
}
}
}
render() {
const currentLocationPath = this.props.location.pathname;
const isAuthenticated = this.isAuthenticated();
const resetPasswordPathname = currentLocationPath.includes('/api/v1/resetPassword/');
if (!isAuthenticated) {
return (
<div className="App d-flex flex-column">
{/* Navbar with brand logo and language change dropdown and signup/login button */}
< Header />
{/* Main Section with RelayStream Animation graphic and forms */}
<div className="container py-4 py-md-0 pt-lg-4 d-flex flex-grow" >
<div className={'LoginScreen d-flex align-items-center align-items-lg-start ' +
((currentLocationPath === '/login' ||
currentLocationPath === '/signup' ||
currentLocationPath === '/forgot-password' ||
resetPasswordPathname) ? 'justify-content-around' : 'justify-content-center')}>
{/* RelayStream Animation graphic */}
<RelayAnimation />
{/* forms to switch between based on path change by <Router/> */}
<Route path="/login" component={(props) => <UserLoginForm {...props} notifySuccess={this.notifySuccess} notifyError={this.notifyError} toggleLoader={this.toggleLoader} />} />
<Route path="/signup" component={(props) => <UserSignUpForm {...props} notifySuccess={this.notifySuccess} notifyError={this.notifyError} toggleLoader={this.toggleLoader} />} />
<Route path="/forgot-password" component={(props) => <PassResetReqForm {...props} notifySuccess={this.notifySuccess} notifyError={this.notifyError} toggleLoader={this.toggleLoader} />} />
<Route path="/api/v1/resetPassword/:token" component={(props) => <PassResetForm {...props} notifySuccess={this.notifySuccess} notifyError={this.notifyError} toggleLoader={this.toggleLoader} />} />
</div>
</div >
{/* Footer with copyright message */}
<Footer />
<div className={this.state.loading ? 'loader flex-column' : 'd-none'}>
<span className="loader__title">Loading...</span>
<BarLoader color={'#36D7B7'} loading={this.state.loading} />
</div>
{/* React toastify for toast notification */}
<ToastContainer className={{ textAlign: 'center' }} progressClassName={css({ background: '#007aff' })} />
</div >
);
} else {
return <Redirect to={'/dashboard'} />;
}
}
}
export default withRouter(HomePage);
UserLoginForm.js
import React, { Component } from 'react';
import { Link, Redirect } from 'react-router-dom';
import $ from 'jquery';
import { Animated } from 'react-animated-css';
import SocialButton from '../SocialButton/SocialButton';
// ---------------- Form components
import Form from 'react-validation/build/form';
import Button from 'react-validation/build/button';
// ---------------- Custom Form components & validations
import { Email, Password, required, noSpace, minChar8, email } from '../formValidation';
import FontAwesomeIcon from '#fortawesome/react-fontawesome';
import facebook from '#fortawesome/fontawesome-free-brands/faFacebookF';
import google from '#fortawesome/fontawesome-free-brands/faGooglePlusG';
import './UserLoginForm.css';
class UserLoginForm extends Component {
constructor(props) {
super(props);
this.state = {
fireRedirect: false
};
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSocialLogin = (user) => {
const provider = user._provider;
const name = user._profile.name;
const email = user._profile.email;
const profilePic = user._profile.profilePicURL;
const token = user._token.accessToken;
const data = { provider, name, email, profilePic, token };
console.log(data);
const url = '/api/v1/loginWithFacekbook'; // social login's api url
// api call for social logins
$.ajax({
url: url,
dataType: 'json',
type: 'POST',
data: data,
success: function (res) {
console.log('success response after api call ===>>', res);
const generatingAuthToken = res.object.generatingAuthToken;
const apikey = generatingAuthToken.apiKey;
const authToken = generatingAuthToken.authToken;
localStorage.setItem('apiKey', apikey);
localStorage.setItem('authToken', authToken);
// if social login was successful then redirect user to dashboard
this.setState({ fireRedirect: true });
}.bind(this),
error: function (xhr, status, err) {
console.log(status);
// if there was network issue notify user to try again later or refresh page
this.props.notifyError(err.toString());
console.error(url, status, err.toString());
}.bind(this)
});
}
handleSocialLoginFailure = (err) => {
console.error(err)
}
handleInputChange(event) {
const target = event.target;
const value = target.value;
const name = target.name;
// input field animation code - adds class to current focused input field's parent
if (value) {
target.parentElement.classList.add('input--filled');
} else {
target.parentElement.classList.remove('input--filled');
}
this.setState({
[name]: value
});
}
handleSubmit(event) {
event.preventDefault();
// show loading spinner
this.props.toggleLoader();
// get data from all field in form
const data = this.form.getValues();
const url = '/api/v1/loginUser'; // user login api url
// api call to generate token and apikey and login user to dashboard
$.ajax({
url: url,
dataType: 'json',
type: 'POST',
data: data,
success: function (res) {
console.log('success response after api call ===>>', res);
const obj = res.object;
const loginStatus = res.status;
const msg = res.message;
// check if authToken and apiKey was received
if (obj) {
// if data is found in database check if credentials provided were correct
if (loginStatus) {
JSON.stringify(obj);
// save apiKey and token in loacalStorage
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
let val = obj[key];
localStorage.setItem(key, val);
}
}
// turn off loader spinner
this.props.toggleLoader();
this.setState({ fireRedirect: true });
// if credentials were correct accept login then redirect user to dashboard
} else { // if credentials were wrong
// turn off loader spinner
// this.props.toggleLoader();
// then notify about wrong credentials
this.props.notifyError(msg);
}
} else { // if data was not found in database notify user to signup first
this.props.notifyError(msg);
// turn off loader spinner
// this.props.toggleLoader();
}
}.bind(this),
error: function (xhr, status, err) {
console.log(status);
// if there was network issue notify user to try again later or refresh page
this.props.notify(err.toString());
console.error(url, status, err.toString());
}.bind(this)
});
}
render() {
const { fireRedirect } = this.state;
return (
<Animated className="form-animation" animationIn="fadeInRight" animationOut="fadeOutLeft" isVisible={true}>
<Form className="userLoginForm" ref={c => { this.form = c }} onSubmit={this.handleSubmit} noValidate>
<h2 className="formTitle text-center">LOG IN</h2>
<Email
required
pattern="[a-z0-9._%+-]+#[a-z0-9.-]+\.[a-z]{2,3}$"
id="email"
name="email"
type="email"
className="input__field input__field--madoka"
onChange={this.handleInputChange}
validations={[required, email]} />
{/* must wrap Password Field Component with "div.form-group" */}
<div className="form-group">
<Password
required
id="password"
name="password"
type="password"
minLength="8"
className="input__field input__field--madoka"
onChange={this.handleInputChange}
validations={[noSpace, required, minChar8]} />
{/* Optional Link Component below...
Note: If there is no requirement of Link or any Other Element just below <Password/> input field
in entire project then the wrapping "div.form-group" can also be put inside
Password Component's Template Located in formValidation.js file*/}
<Link to="/forgot-password" className="float-right forgotPassword">
<small>Forgot password ?</small>
</Link>
</div>
<div className="form-group submitGroup text-center">
<Button type="submit" className="btn btn--submit btn-rounded btn-outline-primary mx-auto">LOG IN</Button>
</div>
{/* login buttons for facebook and google login */}
<div className="socialLogin mx-auto">
{/* <a href="#" className="socialBtn socialBtn--facebook rounded-circle">
<FontAwesomeIcon icon={facebook} />
</a> */}
<SocialButton
className="socialBtn socialBtn--facebook rounded-circle"
provider='facebook' appId='873380466175223'
onLoginSuccess={this.handleSocialLogin}
onLoginFailure={this.handleSocialLoginFailure}
redirect="/dashboard">
<FontAwesomeIcon icon={facebook} />
</SocialButton>
<span className="seperator" />
<SocialButton
className="socialBtn socialBtn--googlePlus rounded-circle"
provider="google"
appId="843586925977-d7j31p5j0me5kqvcp29nr9s37reg5b5u.apps.googleusercontent.com"
onLoginSuccess={this.handleSocialLogin}
onLoginFailure={this.handleSocialLoginFailure}>
<FontAwesomeIcon icon={google} />
</SocialButton>
{/* <a href="#" className="socialBtn socialBtn--googlePlus rounded-circle">
<FontAwesomeIcon icon={google} />
</a> */}
</div>
{/* code to redirect user to dashboard page after successful login */}
{fireRedirect && (<Redirect to={'/dashboard'} />)}
</Form>
</Animated>
);
}
}
export default UserLoginForm;
UserSignUpForm.js
import React, { Component } from 'react';
import { Redirect } from 'react-router-dom';
import $ from 'jquery';
import { Animated } from 'react-animated-css';
// ---------------- Form components
import Form from 'react-validation/build/form';
import Button from 'react-validation/build/button';
// ---------------- Custom Form components & validations
import { UserName, Email, NewPassword, ConfirmPassword, noSpace, required, minChar8, email, confirmPassword } from '../formValidation';
import './UserSignUp.css';
class UserSignUpForm extends Component {
constructor(props) {
super(props);
this.state = {
userName: '',
email: '',
password: '',
confirmPassword: '',
fireRedirect: false
};
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.value;
const name = target.name;
// input field animation code - adds class to current focused input field's parent
if (value) {
target.parentElement.classList.add('input--filled');
} else {
target.parentElement.classList.remove('input--filled');
}
this.setState({
[name]: value
});
}
handleSubmit(event) {
event.preventDefault();
const data = this.form.getValues();
console.log(data);
// api call to sign up user
$.ajax({
url: '/api/v1/user',
dataType: 'json',
type: 'POST',
data: data,
success: function (res) {
console.log('success response after api call ===>>', res);
const signUpStatus = res.status;
const msg = res.message;
if (signUpStatus) {
// if signup was successful notify user
this.props.notifySuccess(msg);
// redirect user to login form
this.setState({ fireRedirect: true });
} else {
this.props.notifyError(msg); // notify user on signup fail
}
}.bind(this),
error: function (xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
}
render() {
const { fireRedirect } = this.state;
return (
<Animated className="form-animation" animationIn="fadeInRight" animationOut="fadeOutLeft" isVisible={true}>
<Form className="userSignUpForm" ref={c => { this.form = c }} onSubmit={this.handleSubmit}>
<h2 className="formTitle text-center">SIGN UP</h2>
<UserName
required
id="userName"
name="userName"
ref={c => { this.UserName = c }}
value={this.state.userName}
type="text"
className="input__field input__field--madoka"
validations={[required]}
onChange={this.handleInputChange} />
<Email
required
pattern="[a-z0-9._%+-]+#[a-z0-9.-]+\.[a-z]{2,3}$"
id="email"
name="email"
ref={c => { this.Email = c }}
value={this.state.email}
type="email"
className="input__field input__field--madoka"
validations={[required, email]}
onChange={this.handleInputChange} />
<div className="form-group">
<NewPassword
required
id="password"
name="password"
ref={c => { this.NewPassword = c }}
value={this.state.password}
type="password"
minLength="8"
className="input__field input__field--madoka"
onChange={this.handleInputChange}
validations={[noSpace, required, minChar8]} />
</div>
<div className="form-group">
<ConfirmPassword
required
id="confirmPassword"
name="confirmPassword"
ref={c => { this.ConfirmPassword = c }}
value={this.state.confirmPassword}
type="password"
minLength="8"
className="input__field input__field--madoka"
onChange={this.handleInputChange}
validations={[noSpace, required, confirmPassword]} />
</div>
<div className="form-group submitGroup text-center">
<Button type="submit" className="btn btn--submit btn-rounded btn-outline-primary mx-auto">SIGN UP</Button>
</div>
{/* code to redirect user to dashboard page after successful login */}
{fireRedirect && (<Redirect to={'/login'} />)}
</Form>
</Animated>
);
}
}
export default UserSignUpForm;
i am facing many issues. first i have a spinner in homepage.js which shows as overlay on whole page when this.state.loading = true, initially it is set to False in constructor.
Issues 1.) when we submit the login form (if signup was done already ) the loader shows for fraction of second on screen but " this.setState({ fireRedirect: true }); " this code is supposed to redirect user to dashboard which it does but gives error in console :
index.js:2178 Warning: Cannot update during an existing state transition (such as within `render` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`.
index.js:2178 Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.
Please check the code for the UserLoginForm component.
Issue 2.) If i create a new user from UserSignUpForm which redirects us to UserLoginForm. now if i try to login i get only this error:
index.js:2178 Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.
Please check the code for the UserLoginForm component.
Issue 3.) If i remove or comment "this.toggleLoader();" from the ajax's success functions right before " this.setState({ fireRedirect: true }); " this line. then the loader shows on screen but doesn't go away even page doesn't redirect and console gives this error:
index.js:2178 Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.
Please check the code for the UserLoginForm component.

How to work with axios.put and react?

I am trying create a simple crud system with react redux and form-redux.
The code below but does not work and gives error.
First I created an action for update and then created a reducer for that.
And then created component to use the action.
Let me know how to get this to work.
//-------------action--------------
export const EDIT_POST = 'EDIT_POST';
export const editPost = (id) => {
const request = axios.put(`${BOOK_URL}/books/${id}`);
return {
type: EDIT_POST,
payload: id,
}
};
//---------------- reducer-----------------
case EDIT_POST: {
return {...state, post: action.payload.data}
}
//----------------route--------------
<Route path='/posts/edit/:id' component={PostEdit}/>
//-------------------PostEdit---------------
class PostEdit extends Component {
componentDidMount = () => {
this.props.editPost(this.props.match.params.id);
console.log(this.props.editPost(this.props.match.params.id));
};
renderField = field => {
const {meta: {touched, error}} = field;
const className = `form-group ${touched && error ? 'has-danger' : ''}`;
return (
<div className='has-danger'>
<label>{field.label}</label>
<input type="text" {...field.input} className="form-control"/>
<div className="text-help">
{touched ? error : ''}
</div>
</div>
);
};
render() {
const {handleSubmit} = this.props;
return (
<form onSubmit={handleSubmit(this.onSubmitForm)}>
<Field name="title" label="Title" component={this.renderField}/>
<Field name="author" label="Author" component={this.renderField}/>
<Field name="description" label="Description" component={this.renderField}/>
<Field name="publicationDate" label="PublicationDate" component={this.renderField}/>
<button type='submit' className="btn btn-primary">Submit</button>
<Link to='/' className='btn btn-danger'>Cancel</Link>
</form>
);
}
}
export default reduxForm({
form :'updateForm'
})(connect(null, {editPost})(PostEdit));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Could you tell what error you are getting?
You have to change your action like
export const fetchPosts = () => {
return (dispatch) => {
axios.get(`${BOOK_URL}/books`).then((response) => {
return dispatch({
type: FETCH_POSTS,
payload: // your response here
});
})
}
}

Resources