i am not getting displayed the post - javascript

in this i have put request the api its being consoled i want to show it on my screen like crud can anyone help me with it i have used axios.put i think i havnt added the code plaese help me.please help me with this i am a beginner in react.
my api link [restapi]
i am posting my code bekow please go through it:
import axios from "axios";
import react, { useEffect, useState } from "react";
import './App.css'
export default function App() {
const [users, setUsers] = useState([]);
const [searchTerm, setsearchTerm] = useState("");
const [title, setTitle] = useState('');
const [body, setBody] = useState('');
const postData =(e)=>{
e.preventDefault();
axios.post("https://reqres.in/api/users?page=1",{
title,
body
} ).then(res=>console.log('posting',res))
}
useEffect(() => {
axios.get("https://reqres.in/api/users?page=1").then((res) => {
setUsers(res.data);
});
}, []);
return (
<div className="App">
<div className="flex">
<input
onChange={(e) => {
setsearchTerm(e.target.value);
} }
type="text"
placeholder="search"
className="form-control"
style={{
width: "80%",
borderRadius: "30px 0 30px",
justifyContent: "center",
marginLeft: "100px",
}} />
<br/>
<br/>
<form>
<label>first_name</label>
<input value={title} onChange={(e)=>setTitle(e.target.value)}/>
<label>email</label>
<input value={body} onChange={(e)=>setBody(e.target.value)}/>
<button onClick={postData}>post</button>
{users?.data?.filter((val) => {
if (searchTerm === "") {
return val;
} else if (val.first_name.toLowerCase().includes(searchTerm.toLowerCase())) {
return val;
}
}).map((datas) => (
<div key={datas.id}>
<p>
<strong>{datas.first_name}</strong>
</p>
<p>{datas.email}</p>
<img key={datas.avatar} src={datas.avatar} />
</div>
))}
</form>
</div>
</div>
);
}

Try the below code. I hope that's how you wanted it to work.
Post request to api - https://reqres.in/api/users?page=1 return data in different form than the api - https://reqres.in/api/users?page=1. So in order to add and show the entered data in the users list, you have to customized the data before adding it to the users useState. Like this:
setUsers([
...users,
{
id: res.data.id,
first_name: res.data.title,
email: res.data.body,
avatar: "https://reqres.in/img/faces/5-image.jpg",
},
]);
Note - I have used a random image while adding the entered data to the users list. As no avatar was being returned from the api.
Full working code:
import axios from "axios";
import react, { useEffect, useState } from "react";
import "./App.css";
export default function App() {
const [users, setUsers] = useState([]);
const [searchTerm, setsearchTerm] = useState("");
const [title, setTitle] = useState("");
const [body, setBody] = useState("");
const postData = (e) => {
e.preventDefault();
axios
.post("https://reqres.in/api/users?page=1", {
title,
body,
})
.then((res) => {
setUsers([
...users,
{
id: res.data.id,
first_name: res.data.title,
email: res.data.body,
avatar: "https://reqres.in/img/faces/5-image.jpg",
},
]);
});
};
useEffect(() => {
axios.get("https://reqres.in/api/users?page=1").then((res) => {
setUsers(res.data.data);
});
}, []);
return (
<div className="App">
<div className="flex">
<input
onChange={(e) => {
setsearchTerm(e.target.value);
}}
type="text"
placeholder="search"
className="form-control"
style={{
width: "80%",
borderRadius: "30px 0 30px",
justifyContent: "center",
marginLeft: "100px",
}}
/>
<br />
<br />
<form>
<label>first_name</label>
<input value={title} onChange={(e) => setTitle(e.target.value)} />
<label>email</label>
<input value={body} onChange={(e) => setBody(e.target.value)} />
<button onClick={postData}>post</button>
{users
.filter((val) => {
if (searchTerm === "") {
return val;
} else if (
val.first_name.toLowerCase().includes(searchTerm.toLowerCase())
) {
return val;
}
})
.map((datas) => (
<div key={datas.id}>
<p>
<strong>{datas.first_name}</strong>
</p>
<p>{datas.email}</p>
<img key={datas.avatar} src={datas.avatar} />
</div>
))}
</form>
</div>
</div>
);
}

Related

Facing some errors while implementing a class component method to functional component method in a restaurant rating management project

RestaurantList.js
import React, { Component } from "react";
import { Table } from 'react-bootstrap';
import { Link } from 'react-router-dom'
export default class RestaurantList extends Component {
constructor() {
super();
this.state = {
list: null,
};
}
componentDidMount() {
fetch("http://localhost:3000/restaurant").then((response) => {
response.json().then((result) => {
this.setState({ list: result });
});
});
}
render() {
return (
<div>
<h1>List</h1>
{
this.state.list ?
<div>
<Table striped bordered hover>
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Email</th>
<th>Rating</th>
<th>City</th>
<th>Operation</th>
</tr>
</thead>
<tbody>
{
this.state.list.map((item, i) =>
<tr>
<td>{item.id}</td>
<td>{item.name}</td>
<td>{item.email}</td>
<td>{item.rating}</td>
<td>{item.address}</td>
<td><Link to={"/update/" + item.id} style={{ color: 'blue', textDecoration: 'inherit' }}>Edit</Link></td>
</tr>)
}
</tbody>
</Table>
</div>
:
<p>Please Wait...</p>
}
</div>
);
}
}
RestaurantUpdate.js
In Class Component Method (It is correct)
import React, { Component } from 'react';
import NavBarManu from './NavBarManu'
class RestaurantUpdate extends Component {
constructor()
{
super();
this.state = {
name: null,
email: null,
address: null,
rating: null,
id:null,
}
}
componentDidMount()
{
fetch('http://localhost:3000/restaurant/'+this.props.match.params.id).then((response) => {
response.json().then((result) => {
console.warn(result)
this.setState({
name:result.name,
email:result.email,
id:result.id,
rating:result.rating,
address:result.address
})
})
})
}
update()
{
fetch('http://localhost:3000/restaurant/'+this.state.id, {
method: "PUT",
headers:{
'Content-Type':'application/json'
},
body: JSON.stringify(this.state)
}).then((result)=>{
result.json().then((resp)=>{
alert("Restaurant has heen Update")
})
})
}
render() {
return (
<div>
<NavBarManu />
<h1>Restaurant Update</h1>
<div>
<input onChange={(event) => { this.setState({ name: event.target.value }) }}
placeholder="Restaurant Name" value={this.state.name} /> <br /><br />
<input onChange={(event) => { this.setState({ email: event.target.value }) }}
placeholder="Restaurant Email" value={this.state.email} /> <br /><br />
<input onChange={(event) => { this.setState({ rating: event.target.value }) }}
placeholder="Restaurant Rating" value={this.state.rating}/> <br /><br />
<input onChange={(event) => { this.setState({ address: event.target.value }) }}
placeholder="Restaurant Address" value={this.state.address}/> <br /><br />
<button onClick={() => { this.update() }}>Update Restaurant</button>
</div>
</div>
);
}
}
export default RestaurantUpdate;
In Functional Component(Facing some errors)
import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
const RestaurantUpdate = () => {
const [name, setName] = useState(null);
const [email, setEmail] = useState(null);
const [address, setAddress] = useState(null);
const [rating, setRating] = useState(null);
const [id, setId] = useState(null);
//Want to use it like CompoundDidMount
useEffect(() => {
fetch('http://localhost:3000/restaurant' / +id).then((response) => {
response.json().then((result) => {
console.warn(result)
setName(result.name);
setEmail(result.email);
setId(result.id);
setAddress(result.address);
setRating(result.rating);
})
})
}, []);
//Want to display all the states in the console with their respective values. But i am unable to do it.
useEffect(() => {
console.warn(name);
}, [id]);
return (
<div>
<h1>Update</h1>
<div>
<input onChange={(event) => { this.setState({ name: event.target.value }) }}
placeholder="Restaurant Name" /> <br /><br />
<input onChange={(event) => { this.setState({ email: event.target.value }) }}
placeholder="Restaurant Email" /> <br /><br />
<input onChange={(event) => { this.setState({ rating: event.target.value }) }}
placeholder="Restaurant Rating" /> <br /><br />
<input onChange={(event) => { this.setState({ address: event.target.value }) }}
placeholder="Restaurant Address" /> <br /><br />
<button onClick={() => { this.update() }}>Update Restaurant</button>
</div>
</div>
);
};
export default RestaurantUpdate;
I was expecting display of all the state in the console with the their respective data. But it is showing null values.
I am facing some errors in implementing componentDidMount() in function component using hooks and in setState().
Basically I just want to use given Class Component RestaurantUpdate.js in functional component way.
Definitely there are some syntax errors and i am facing some difficulties in implementing them. So please point out the error and provide me the right solution.
Blockquote
Add a conditional render and see if it works.
import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
const RestaurantUpdate = () => {
const [name, setName] = useState(null);
const [email, setEmail] = useState(null);
const [address, setAddress] = useState(null);
const [rating, setRating] = useState(null);
const [id, setId] = useState(null);
const [result, setResult] = useState(null);
//Want to use it like CompoundDidMount
useEffect(() => {
fetch('http://localhost:3000/restaurant' / +id).then((response) => {
response.json().then((result) => {
console.warn(result)
setResult(result);
setName(result.name);
setEmail(result.email);
setId(result.id);
setAddress(result.address);
setRating(result.rating);
})
})
}, []);
//Want to display all the states in the console with their respective values. But i am unable to do it.
useEffect(() => {
console.warn(name);
}, [id]);
return (
<>
{
result ? (
<div>
<h1>Update</h1>
<div>
<input onChange={(event) => { setName(event.target.value) }} value={name}
placeholder="Restaurant Name" /> <br /><br />
<input onChange={(event) => { setEmail(event.target.value) }} value={email}
placeholder="Restaurant Email" /> <br /><br />
<input onChange={(event) => { setRating(event.target.value) }} value={rating}
placeholder="Restaurant Rating" /> <br /><br />
<input onChange={(event) => { setAddress(event.target.value) }} value={address}
placeholder="Restaurant Address" /> <br /><br />
<button onClick={() => { update() }}>Update Restaurant</button>
</div>
</div>
) : (<div>loading</div>)
}
</>
);
};
export default RestaurantUpdate;
There are a few things to address here that probably will help you to achieve the desired result.
First is the id, probably it should come from the a call to useParams right? if so, no need to declare it as a state.
const { id } = useParams();
Then, in the useEffect even though you want to simulate compoundDidMount the recommended solution is to include in the deps array all the values used internally in the useEffect. this link hooks docs is super helpful.
Next, you probably is having some warnings in the console complaining about "value" prop on "input" should not be null and A component is changing an uncontrolled input to be controlled, this can be avoided just by setting an initial state for the inputs different of null or undefined, and this could be:
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [address, setAddress] = useState("");
const [rating, setRating] = useState(0);
or also by using the technique displayed in the previous answers will help you to remove from these warnings.
Also in your example the value field was missing in the inputs
<input
onChange={(event) => setName(event.target.value)}
placeholder="Restaurant Name"
value={name} />
And I guess with these tweaks you should be fine. I've put together a sandbox that might help you to unfold everything. example

TypeError: Converting circular structure to JSON when sending a post request through axios

Im getting this error when I send a post request to the server when the role for the user is seller for which there are 2 extra properties for the JSON : resName and resAddress. I am also using placeautocomplete (from google) to get the address of the restaurant (the name of it can be anything for the time being).
Register.js:
import logo from './logo.svg';
import './App.css';
import React, { Component, useEffect } from 'react';
import { useState } from 'react';
import axios from 'axios';
import LocationSearchInput from './placeComplete';
function Register() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [role, setRole] = useState("seller");
const [resName, setResName] = useState("");
const [resAddress, setResAddress] = useState(React.createRef());
async function registerUser(e){
e.preventDefault();
if (role === 'seller'){
const restaurantAddress = resAddress.current
console.log(restaurantAddress.state.address, resName)
}
const response = await axios.post('/api/users/register',
{
name,
email,
password,
resName,
resAddress,
role
}
).then(
res => {
console.log(res.data)
}
)
}
function registerRestaurant(){
if (role === 'seller'){
return(
<div>
<h4>Restaurant Name:</h4> <br />
<input type='text'
placeholder='Restaurant Name'
value={resName}
onChange={(e) => setResName(e.target.value)}
/>
<br />
<LocationSearchInput ref={resAddress} />
</div>
);
}
}
return (
<div>
<form onSubmit={registerUser}>
<input type="name" placeholder="Name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<br />
<input type="email" placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<br />
<input type="password" placeholder="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<br />
<input type='radio' value='customer'
checked={role === 'customer'}
onChange={(e) => {
setRole(e.target.value)
}}
/>
customer
<br />
<input type='radio' value='seller'
checked={role === 'seller'}
onChange={(e) => {
setRole(e.target.value)
}}
/>
seller
<br />
{registerRestaurant()}
<input type='submit' value='Register' />
</form>
</div>
);
}
export default Register;
placeComplete.js:
import React from 'react';
import PlacesAutocomplete, {
geocodeByAddress,
getLatLng,
} from 'react-places-autocomplete';
class LocationSearchInput extends React.Component {
constructor(props) {
super(props);
this.state = { address: '' };
}
handleChange = address => {
this.setState({ address });
};
handleSelect = address => {
geocodeByAddress(address)
.then(results => getLatLng(results[0]))
.then(latLng => console.log('Success', latLng))
.then(this.setState({address: address}))
.catch(error => console.error('Error', error));
};
render() {
return (
<PlacesAutocomplete
value={this.state.address}
onChange={this.handleChange}
onSelect={this.handleSelect}
>
{({ getInputProps, suggestions, getSuggestionItemProps, loading }) => (
<div>
<input
{...getInputProps({
placeholder: 'Search Places ...',
className: 'location-search-input',
})}
/>
<div className="autocomplete-dropdown-container">
{loading && <div>Loading...</div>}
{suggestions.map(suggestion => {
const className = suggestion.active
? 'suggestion-item--active'
: 'suggestion-item';
// inline style for demonstration purpose
const style = suggestion.active
? { backgroundColor: '#fafafa', cursor: 'pointer' }
: { backgroundColor: '#ffffff', cursor: 'pointer' };
return (
<div
{...getSuggestionItemProps(suggestion, {
className,
style,
})}
>
<span>{suggestion.description}</span>
</div>
);
})}
</div>
</div>
)}
</PlacesAutocomplete>
);
}
}
export default LocationSearchInput;
I am also getting the following warning when I start typing in resAddress:
react_devtools_backend.js:4026 Warning: Each child in a list should have a unique "key" prop. Check the render method of `PlacesAutocomplete`. See https://reactjs.org/link/warning-keys for more information.
Mind you the server is accepting requests through postman.
This error usually gets thrown if you're not sending proper JSON. Your problem seems to happen here:
const response = await axios.post('/api/users/register',
{
name,
email,
password,
resName,
resAddress,
role
}
).then(
res => {
console.log(res.data)
}
)
Since resAddress is a ref (not proper JSON):
const [resAddress, setResAddress] = useState(React.createRef());
Change to something like this and you should be fine:
{
/* ... */
resAddress: resAddress.current.state.address
/* ... */
}

Not getting pre-filled state value from redux when user try to edit the form?

I am trying to get the state from redux store and trying to fill the input field from state. If user in edit mode. In edit mode, we normally show the prefilled value in input field. But what is wrong with the below approach?
I am able to store single user successfully in reducer but in component i am not getting. Sometimes i get the value. Overall, it's very inconsistent.
import React, { useState, useEffect } from "react";
import { makeStyles } from "#material-ui/core/styles";
import TextField from "#material-ui/core/TextField";
import Button from "#material-ui/core/Button";
import { useSelector, useDispatch } from "react-redux";
import { useHistory, useParams } from "react-router-dom";
import { addUser, getSingleUser, updateUser } from "../redux/actions";
const useStyles = makeStyles((theme) => ({
root: {
marginTop: 100,
"& > *": {
margin: theme.spacing(1),
width: "45ch",
},
},
}));
const initialState = {
name: "",
address: "",
contact: "",
email: "",
};
const EditUser = () => {
let { id } = useParams();
const { user } = useSelector((state) => state.users);
console.log("user", user);
const [state, setState] = useState(user);
const [error, setError] = useState("");
const { name, address, email, contact } = state;
const classes = useStyles();
const history = useHistory();
let dispatch = useDispatch();
const onInputChange = (e) => {
let { name, value } = e.target;
setState({ ...state, [name]: value });
};
useEffect(() => {
dispatch(getSingleUser(id));
}, []);
const handlSubmit = (e) => {
e.preventDefault();
console.log("name", name);
if (!name || !email || !address || !contact) {
setError("Please fill all Input Field");
} else {
dispatch(updateUser(state, id));
setError("");
history.push("/");
}
};
return (
<>
<Button
style={{ width: "100px", marginTop: "20px" }}
variant="contained"
type="submit"
color="secondary"
onClick={() => history.push("/")}
>
Go Back
</Button>
<h2>Edit user</h2>
{error && <h3 style={{ color: "red" }}>{error}</h3>}
<form
className={classes.root}
noValidate
autoComplete="off"
onSubmit={handlSubmit}
>
<TextField
id="standard-basic"
label="Name"
value={name}
name="name"
onChange={onInputChange}
type="text"
/>
<br />
<TextField
id="standard-basic"
value={email}
name="email"
label="Email"
type="email"
onChange={onInputChange}
/>
<br />
<TextField
id="standard-basic"
value={contact}
name="contact"
label="Contact"
type="number"
onChange={onInputChange}
/>
<br />
<TextField
id="standard-basic"
label="Address"
value={address}
name="address"
type="text "
onChange={onInputChange}
/>
<br />
<Button
style={{ width: "100px" }}
variant="contained"
type="submit"
color="primary"
>
Update
</Button>
</form>
</>
);
};
export default EditUser;
Below is redux actions logic to get the single user and dispatching an action to store single user value in reducer.
export const getSingleUser = (id) => {
return function (dispatch) {
axios
.get(`${process.env.REACT_APP_API}/${id}`)
.then((resp) => {
console.log("resp", resp);
dispatch(singleUser(resp.data));
})
.catch((error) => console.log(error));
};
};

React js image uploder code with firebase cloud storage gives error?

I am creating a instagram clone and I have made it with react js and database is cloud firestore, and using Cloud Storage for storing images.
I am getting error in ImageUpload.js when I am clicking on upload button and progress bar does not show any progress in console.
The folowing error is shown:
FirebaseStorageError {code_: "storage/invalid-argument", message_: "Firebase Storage: Invalid argument in on at inde…Expected one of the event types: [state_changed].", serverResponse_: null, name_: "FirebaseError"}
code of ImageUpload.js
import React, { useState, useEffect } from "react";
import "./App.css";
import Post from "./Post";
import { db, auth } from "./firebase";
import Modal from "#material-ui/core/Modal";
import { makeStyles } from "#material-ui/core/styles";
import { Button, Input } from "#material-ui/core";
import ImageUpload from "./ImageUpload";
function getModalStyle() {
const top = 50;
const left = 50;
return {
top: `${top}%`,
left: `${left}%`,
transform: `translate(-${top}%, -${left}%)`,
};
}
const useStyles = makeStyles((theme) => ({
paper: {
position: "absolute",
width: 400,
backgroundColor: theme.palette.background.paper,
border: "2px solid #000",
boxShadow: theme.shadows[5],
padding: theme.spacing(2, 4, 3),
},
}));
function App() {
const classes = useStyles();
const [modalStyle] = React.useState(getModalStyle);
const [posts, setsPosts] = useState([]);
const [open, setOpen] = useState(false);
const [openSignIn, setOpenSignIn] = useState(false);
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [email, setEmail] = useState("");
const [user, setUser] = useState(null);
// UseEffect ::--> Runs a piece of code based on a specific condition
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((authUser) => {
if (authUser) {
//user has logged in....
console.log(authUser);
setUser(authUser);
} else {
//user has logged out....
setUser(null);
}
});
return () => {
//perform some cleanup actions
unsubscribe();
};
}, [user, username]);
useEffect(() => {
//this is where the code runs
db.collection("posts").onSnapshot((snapshot) => {
//every time a new post is added,this code firebase
setsPosts(
snapshot.docs.map((doc) => ({
id: doc.id,
post: doc.data(),
}))
);
});
}, []);
const signUp = (event) => {
event.preventDefault();
auth
.createUserWithEmailAndPassword(email, password)
.then((authUser) => {
return authUser.user.updateProfile({
displayName: username,
});
})
.catch((error) => alert(error.message));
setOpen(false);
};
const signIn = (event) => {
event.preventDefault();
auth
.signInWithEmailAndPassword(email, password)
.catch((error) => alert(error.message));
setOpenSignIn(false);
};
return (
<div className="app">
{user?.displayName ? (
<ImageUpload username={user.displayName} />
) : (
<h3>Sorry you need to login to upload</h3>
)}
<Modal open={open} onClose={() => setOpen(false)}>
<div style={modalStyle} className={classes.paper}>
<form className="app__signup">
<center>
<img
src="https://www.instagram.com/static/images/web/mobile_nav_type_logo-2x.png/1b47f9d0e595.png"
alt=""
/>
</center>
<Input
placeholder="usermane"
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<Input
placeholder="email"
type="text"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<Input
placeholder="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<Button type="submit" onClick={signUp}>
Sign Up
</Button>
</form>
</div>
</Modal>
<Modal open={openSignIn} onClose={() => setOpenSignIn(false)}>
<div style={modalStyle} className={classes.paper}>
<form className="app__signup">
<center>
<img
src="https://www.instagram.com/static/images/web/mobile_nav_type_logo-2x.png/1b47f9d0e595.png"
alt=""
/>
</center>
<Input
placeholder="email"
type="text"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<Input
placeholder="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<Button type="submit" onClick={signIn}>
Sign Up
</Button>
</form>
</div>
</Modal>
<div className="app__header">
<img
className="app__headerImage"
src="https://www.instagram.com/static/images/web/mobile_nav_type_logo-2x.png/1b47f9d0e595.png"
alt=""
/>
</div>
{user ? (
<Button onClick={() => auth.signOut()}>Log Out</Button>
) : (
<div className="app__loginContainer">
<Button onClick={() => setOpenSignIn(true)}>Sign In</Button>
<Button onClick={() => setOpen(true)}>Sign Up</Button>
</div>
)}
{/* <h1>Lets built ig-clone with React</h1> */}
{posts.map(({ id, post }) => (
<Post
key={id}
username={post.username}
caption={post.caption}
imageUrl={post.imageUrl}
/>
))}
{/* <Post
username="cleverqazi"
caption="WoW is works"
imageUrl="https://pbs.twimg.com/profile_images/446356636710363136/OYIaJ1KK_400x400.png"
/>
<Post
username="ssssangha"
caption="Dope"
imageUrl="https://images.unsplash.com/photo-1599687266197-6c66c083b39c?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1534&q=80https://images.unsplash.com/photo-1599687266197-6c66c083b39c?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9"
/>
<Post
username="amatsf"
caption="This is fun Project"
imageUrl="https://images.unsplash.com/photo-1600872844932-f95ce063b94c?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9"
/>
Post */}
</div>
);
}
export default App;
code from App.js
import React, { useState, useEffect } from "react";
import "./App.css";
import Post from "./Post";
import { db, auth } from "./firebase";
import Modal from "#material-ui/core/Modal";
import { makeStyles } from "#material-ui/core/styles";
import { Button, Input } from "#material-ui/core";
import ImageUpload from "./ImageUpload";
function getModalStyle() {
const top = 50;
const left = 50;
return {
top: `${top}%`,
left: `${left}%`,
transform: `translate(-${top}%, -${left}%)`,
};
}
const useStyles = makeStyles((theme) => ({
paper: {
position: "absolute",
width: 400,
backgroundColor: theme.palette.background.paper,
border: "2px solid #000",
boxShadow: theme.shadows[5],
padding: theme.spacing(2, 4, 3),
},
}));
function App() {
const classes = useStyles();
const [modalStyle] = React.useState(getModalStyle);
const [posts, setsPosts] = useState([]);
const [open, setOpen] = useState(false);
const [openSignIn, setOpenSignIn] = useState(false);
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [email, setEmail] = useState("");
const [user, setUser] = useState(null);
// UseEffect ::--> Runs a piece of code based on a specific condition
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((authUser) => {
if (authUser) {
//user has logged in....
console.log(authUser);
setUser(authUser);
} else {
//user has logged out....
setUser(null);
}
});
return () => {
//perform some cleanup actions
unsubscribe();
};
}, [user, username]);
useEffect(() => {
//this is where the code runs
db.collection("posts").onSnapshot((snapshot) => {
//every time a new post is added,this code firebase
setsPosts(
snapshot.docs.map((doc) => ({
id: doc.id,
post: doc.data(),
}))
);
});
}, []);
const signUp = (event) => {
event.preventDefault();
auth
.createUserWithEmailAndPassword(email, password)
.then((authUser) => {
return authUser.user.updateProfile({
displayName: username,
});
})
.catch((error) => alert(error.message));
setOpen(false);
};
const signIn = (event) => {
event.preventDefault();
auth
.signInWithEmailAndPassword(email, password)
.catch((error) => alert(error.message));
setOpenSignIn(false);
};
return (
<div className="app">
{user?.displayName ? (
<ImageUpload username={user.displayName} />
) : (
<h3>Sorry you need to login to upload</h3>
)}
<Modal open={open} onClose={() => setOpen(false)}>
<div style={modalStyle} className={classes.paper}>
<form className="app__signup">
<center>
<img
src="https://www.instagram.com/static/images/web/mobile_nav_type_logo-2x.png/1b47f9d0e595.png"
alt=""
/>
</center>
<Input
placeholder="usermane"
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<Input
placeholder="email"
type="text"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<Input
placeholder="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<Button type="submit" onClick={signUp}>
Sign Up
</Button>
</form>
</div>
</Modal>
<Modal open={openSignIn} onClose={() => setOpenSignIn(false)}>
<div style={modalStyle} className={classes.paper}>
<form className="app__signup">
<center>
<img
src="https://www.instagram.com/static/images/web/mobile_nav_type_logo-2x.png/1b47f9d0e595.png"
alt=""
/>
</center>
<Input
placeholder="email"
type="text"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<Input
placeholder="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<Button type="submit" onClick={signIn}>
Sign Up
</Button>
</form>
</div>
</Modal>
<div className="app__header">
<img
className="app__headerImage"
src="https://www.instagram.com/static/images/web/mobile_nav_type_logo-2x.png/1b47f9d0e595.png"
alt=""
/>
</div>
{user ? (
<Button onClick={() => auth.signOut()}>Log Out</Button>
) : (
<div className="app__loginContainer">
<Button onClick={() => setOpenSignIn(true)}>Sign In</Button>
<Button onClick={() => setOpen(true)}>Sign Up</Button>
</div>
)}
{/* <h1>Lets built ig-clone with React</h1> */}
{posts.map(({ id, post }) => (
<Post
key={id}
username={post.username}
caption={post.caption}
imageUrl={post.imageUrl}
/>
))}
{/* <Post
username="cleverqazi"
caption="WoW is works"
imageUrl="https://pbs.twimg.com/profile_images/446356636710363136/OYIaJ1KK_400x400.png"
/>
<Post
username="ssssangha"
caption="Dope"
imageUrl="https://images.unsplash.com/photo-1599687266197-6c66c083b39c?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1534&q=80https://images.unsplash.com/photo-1599687266197-6c66c083b39c?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9"
/>
<Post
username="amatsf"
caption="This is fun Project"
imageUrl="https://images.unsplash.com/photo-1600872844932-f95ce063b94c?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9"
/>
Post */}
</div>
);
}
export default App;
code of firebase.js
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
import firebase from "firebase";
const firebaseapp = firebase.initializeApp({
apiKey: "AIzaSyAOozRFYMCWRQYQ4DZg19LB-8naEiL7WDvWE",
authDomain: "instagram-clone-react-cc16f.firebaseapp.com",
databaseURL: "https://instagram-react-cc16f.firebaseio.com",
projectId: "instagram-clone-react-cc6f",
storageBucket: "instagram-clone-react-cc16f.appspot.com",
messagingSenderId: "602134433443",
appId: "1:602189635954:web:d2d9096d64345349101bdeb",
measurementId: "G-CW4M24VATZ",
});
const db = firebaseapp.firestore();
const auth = firebase.auth();
const storage = firebase.storage();
export { db, auth, storage };
You must add handleUpload to the button you send the picture.
function ImageUpload({ username }) {
const [caption, setCaption] = useState("");
const [image, setImage] = useState(null);
const [progress, setProgress] = useState(0);
const handleChange = (e) => {
if (e.target.files[0]) {
setImage(e.target.files[0]);
}
};
const handleUpload = () => {
const uploadTask = storage.ref(`images/${image.name}`).put(image);
uploadTask.on(
"state_changed",
(snapshot) => {
//progress function
const progress = Math.round(
(snapshot.bytesTransferred / snapshot.totalBytes) * 100
);
setProgress(progress);
},
(error) => {
//error function
console.log(error);
alert(error.message);
},
() => {
//complete function
storage
.ref("images")
.child(image.name)
.getDownloadURL()
.then((url) => {
//post image inside db
db.collection("posts").add({
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
caption: caption,
imageUrl: url,
username: username,
});
setProgress(0);
setCaption("");
setImage(null);
});
}
);
};
return (
<div>
{/*
- I want to have ...
- Caption input
- File picture*/}
<progress value={progress} max="100" />
<input
type="text"
placeholder="Enter a caption..."
onChange={(event) => setCaption(event.target.value)}
value={caption}
/>
<input type="file" onChange={handleChange} />
<Button onClick={handleUpload}>Upload</Button>
</div>
);
}
export default ImageUpload;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Setting the value of DatePicker (from antd) in react-hook-form

I'm trying to figure out how to use the DatePicker from antd with react-hook-form.
Currently, my attempt is:
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import useForm from "react-hook-form";
import { withRouter } from "react-router-dom";
import { useStateMachine } from "little-state-machine";
import updateAction from "./updateAction";
import { Input as InputField, Form, Button, DatePicker, Divider, Layout, Typography, Skeleton, Switch, Card, Icon, Avatar } from 'antd';
import Select from "react-select";
const { Content } = Layout
const { Text, Paragraph } = Typography;
const { Meta } = Card;
const { MonthPicker, RangePicker, WeekPicker } = DatePicker;
const Team = props => {
const { register, handleSubmit, setValue, errors } = useForm();
const [ dueDate, setDate ] = useState(new Date());
const [indexes, setIndexes] = React.useState([]);
const [counter, setCounter] = React.useState(0);
const { action } = useStateMachine(updateAction);
const onSubit = data => {
action(data);
props.history.push("./ProposalBudget");
};
// const handleChange = dueDate => setDate(date);
const handleChange = (e) => {
setValue("dueDate", e.target.value);
}
const onSubmit = data => {
console.log(data);
};
const addMilestone = () => {
setIndexes(prevIndexes => [...prevIndexes, counter]);
setCounter(prevCounter => prevCounter + 1);
};
const removeMilestone = index => () => {
setIndexes(prevIndexes => [...prevIndexes.filter(item => item !== index)]);
};
const clearMilestones = () => {
setIndexes([]);
};
useEffect(() => {
register({ name: dueDate }); // custom register antd input
}, [register]);
Note: i have also tried name: {${fieldName}.dueDate - that doesn't work either.
return (
<div>
<HeaderBranding />
<Content
style={{
background: '#fff',
padding: 24,
margin: "auto",
minHeight: 280,
width: '70%'
}}
>
<form onSubmit={handleSubmit(onSubit)}>
{indexes.map(index => {
const fieldName = `milestones[${index}]`;
return (
<fieldset name={fieldName} key={fieldName}>
<label>
Title:
<input
type="text"
name={`${fieldName}.title`}
ref={register}
/>
</label>
<label>
Description:
<textarea
rows={12}
name={`${fieldName}.description`}
ref={register}
/>
</label>
<label>When do you expect to complete this milestone? <br />
<DatePicker
selected={ dueDate }
// ref={register}
InputField name={`${fieldName}.dueDate`}
onChange={handleChange(index)}
//onChange={ handleChange }
>
<input
type="date"
name={`${fieldName}.dueDate`}
inputRef={register}
/>
</DatePicker>
</label>
<Button type="danger" style={{ marginBottom: '20px', float: 'right'}} onClick={removeMilestone(index)}>
Remove this Milestone
</Button>
</fieldset>
);
})}
<Button type="primary" style={{ marginBottom: '20px'}} onClick={addMilestone}>
Add a Milestone
</Button>
<br />
<Button type="button" style={{ marginBottom: '20px'}} onClick={clearMilestones}>
Clear Milestones
</Button>
<input type="submit" value="next - budget" />
</form>
</Content>
</div>
);
};
export default withRouter(Team);
This generates an error that says: TypeError: Cannot read property 'value' of undefined
setValue is defined in handleChange.
I'm not clear on what steps are outstanding to get this datepicker functioning. Do I need a separate select function?
Has anyone figured out how to plug this datepicker in?
I have also tried:
const handleChange = (e) => {
setValue("dueDate", e.target.Date);
}
and I have tried:
const handleChange = (e) => {
setValue("dueDate", e.target.date);
}
but each of these generations the same error
I have built a wrapper component to work with external controlled component easier:
https://github.com/react-hook-form/react-hook-form-input
import React from 'react';
import useForm from 'react-hook-form';
import { RHFInput } from 'react-hook-form-input';
import Select from 'react-select';
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' },
];
function App() {
const { handleSubmit, register, setValue, reset } = useForm();
return (
<form onSubmit={handleSubmit(data => console.log(data))}>
<RHFInput
as={<Select options={options} />}
rules={{ required: true }}
name="reactSelect"
register={register}
setValue={setValue}
/>
<button
type="button"
onClick={() => {
reset({
reactSelect: '',
});
}}
>
Reset Form
</button>
<button>submit</button>
</form>
);
}
try this out, let me know if it makes your life easier with AntD.
/* eslint-disable react/prop-types */
import React, { useState } from 'react';
import { DatePicker } from 'antd';
import { Controller } from 'react-hook-form';
import color from '../../assets/theme/color';
import DatePickerContainer from './DatePickerContainer';
function DatePickerAntd(props) {
const { control, rules, required, title, ...childProps } = props;
const { name } = childProps;
const [focus, setFocus] = useState(false);
const style = {
backgroundColor: color.white,
borderColor: color.primary,
borderRadius: 5,
marginBottom: '1vh',
marginTop: '1vh',
};
let styleError;
if (!focus && props.error) {
styleError = { borderColor: color.red };
}
return (
<div>
<Controller
as={
<DatePicker
style={{ ...style, ...styleError }}
size="large"
format="DD-MM-YYYY"
placeholder={props.placeholder || ''}
onBlur={() => {
setFocus(false);
}}
onFocus={() => {
setFocus(true);
}}
name={name}
/>
}
name={name}
control={control}
rules={rules}
onChange={([selected]) => ({ value: selected })}
/>
</div>
);
}
export default DatePickerAntd;
my container parent use react-hooks-form
const { handleSubmit, control, errors, reset, getValues } = useForm({
mode: 'onChange',
validationSchema: schema,
});
<DatePickerAntd
name="deadline"
title={messages.deadline}
error={errors.deadline}
control={control}
required={isFieldRequired(schema, 'deadline')}
/>
like that, its working for me ;-)
Try this:
<DatePicker
selected={ dueDate }
// ref={register}
InputField name={`${fieldName}.dueDate`}
onChange={()=>handleChange(index)}
//onChange={ handleChange }
>
<input
type="date"
name={`${fieldName}.dueDate`}
inputRef={register}
/>
It looks like if you are using onChange={handleChange(index)} it does not pass a function instead you are passing an execution result of that function.
And if you are trying to access event inside handleChange, you should manually pass if from binding scope otherwise, it will be undefined.
onChange={()=>handleChange(index, event)}

Categories

Resources