Why isnt my dropdown sending data with my onChange - reactjs

So im trying to make a categories post, the backend part works but it isnt sending any data. i think it's something with my onChange. It works if I do it as a single input and manually type in said category but when I try to do it in a dropdown menu it isnt reading the value i think. My backend has an enum of "grinders" and "trays right now.
This is my front end code
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js">
import React from "react";
import axios from "axios";
import { post } from "../services/service";
const Post = () => {
const [title, setTitle] = React.useState("");
const [content, setContent] = React.useState("");
const [price, setPrice] = React.useState("");
const [postPic, setPostPic] = React.useState("");
const [category, setCategory] = React.useState(""); //THIS IS MY HOOK FOR CATEGORIES
const [status, setStatus] = React.useState("");
const createPost = async (e) => {
e.preventDefault();
if (!title || !category) {
setStatus("Please enter a title and category");
} else {
try {
const response = await post("/posts/create", {
title: title,
content: content,
price: "$" + price,
postPic: postPic,
typeOfCategory: category,
});
console.log("DATA", response.data);
} catch (err) {
console.error(err.message);
}
}
};
const handleFileUpload = async (e) => {
try {
// setLoading(true);
const uploadData = new FormData();
uploadData.append("imageUrl", e.target.files[0]);
let response = await post("/posts/add-picture", uploadData);
setPostPic(response.data.path);
// setLoading(false);
} catch (err) {
console.error(err.message);
// setLoading(false);
setStatus("Image must be .png, .jpeg, or .webp");
}
};
return (
<div className="post-page">
<form className="login-inputs" onSubmit={createPost}>
<h1 className="post-title">Create post</h1>
<input
placeholder="Title..."
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<div className="postpic-img-section">
<img
className="postpic-img"
src={
postPic ||
"https://www.freeiconspng.com/thumbs/no-image-icon/no-image-icon-15.png"
}
alt="Profile Picture"
/>
</div>
<textarea
placeholder="Content..."
type="text"
value={content}
onChange={(e) => setContent(e.target.value)}
/>
<input
className="price-input"
placeholder="$0"
type="number"
value={price}
onChange={(e) => setPrice(e.target.value)}
/>
{/* <input
placeholder="category"
type="text"
value={category}
onChange={(e) => setCategory(e.target.value)}
/> */}
<label htmlFor="file-upload" className="custom-file-upload">
<i className="fa fa-cloud-upload">
<img
src="https://www.freeiconspng.com/thumbs/upload-icon/upload-icon-22.png"
alt="Upload"
height="20"
/>
Custom Upload
</i>
</label>
<input id="file-upload" type="file" onChange={handleFileUpload} />
{/* THIS IS WHERE IM TRYING TO MAKE THE DROPDOWN OF THE CATEGORIES */}
<select value={category} onChange={(e) => setCategory(e.target.value)}>
<option value="grinders">grinders</option>
<option value="trays">Trays</option>
</select>
<button>Submit</button>
<p className="login-status">{status}</p>
</form>
</div>
);
};
export default Post;
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

There is nothing wrong with your select handling. I've just copy-pasted your relevant code snippet and it works well.
const App = () => {
const [category, setCategory] = React.useState("")
return (
<div>
<div>typeOfCategory: {category}</div>
<select value={category} onChange={(e) => setCategory(e.target.value)}>
<option value="" disabled>Please select</option>
<option value="grinders">grinders</option>
<option value="trays">Trays</option>
</select>
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Im dumb my token expired and I have a isAuth in my backend

Related

ReactJS select first option doesn't work properly

I have a react app with edit logic with select tag and options for continents and countries. In the continents it seems everything is alright but in countries I can't set a first option. First I must to select another country and then first option is available for set.
This is my code:
import React, { useState, useEffect, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import styles from './editContact.module.css';
import { urls, methods } from '../constants';
import requester from '../services/requester';
import notificationsReceiver from '../services/notificationReceiver';
const EditContact = () => {
const id = window.location.pathname.slice(14);
const navigate = useNavigate();
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [phone, setPhone] = useState('');
const [description, setDescription] = useState('');
const [categories, setCategories] = useState('');
const [areas, setAreas] = useState('');
const [event, setEvent] = useState('');
const [continentId, setContinent] = useState('');
const [countryId, setCountry] = useState('');
const [continents, setContinents] = useState([]);
const [countries, setCountries] = useState([]);
const getContact = useCallback(async () => {
const request = await requester(urls.contacts + '/' + id, methods.get);
const response = await request.json();
setName(response.name);
setEmail(response.email);
setAreas(response.areas);
setCategories(response.categories);
setDescription(response.description);
setEvent(response.event);
setPhone(response.phoneNumber);
setContinent(response.continentId);
setCountry(response.countryId);
}, [id]);
const sendToHome = () => {
navigate(urls.mainPage);
};
const editContact = async (e) => {
e.preventDefault();
await requester(urls.contacts + '/' + id, methods.put, {
name,
email,
phone,
description,
areas,
event,
categories,
continentId,
countryId
}
)
.then(() => {
navigate(urls.mainPage);
notificationsReceiver('Contact is edited successfully!');
})
.catch((e) => {
alert(e.message);
})
};
const getContinents = async () => {
const request = await requester(urls.getContinents, methods.get);
const response = await request.json();
setContinents(response);
};
const getCountries = async () => {
const request = await requester(urls.getCountries, methods.get);
const response = await request.json();
setCountries(response);
};
useEffect(() => {
getContact();
getContinents();
getCountries();
}, [getContact]);
return (
<form className={styles['edit-form']} onSubmit={editContact}>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Name</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setName(e.target.value)} value={name} />
</div>
<label htmlFor="exampleFormControlInput1">Continent</label>
<select className="form-control" id="exampleFormControlSelect1" title="continent" name="continent" onChange={e => setContinent(e.target.value)} value={continentId}>
{continents.map(continent =>
<option key={continent.continentId} value={continent.continentId}>{continent.continentName}</option>
)}
</select>
<label htmlFor="exampleFormControlInput1">Countries</label>
<select className="form-control" id="exampleFormControlSelect1" title="country" name="country" onChange={e => setCountry(e.target.value)} value={countryId}>
{countries.filter(x => x.placeIsContainedInId === continentId).map(country =>
<option key={country.countryId} value={country.countryId}>{country.countryName}</option>
)}
</select>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">eMail</label>
<input type="email" className="form-control" id="exampleFormControlInput1" onChange={e => setEmail(e.target.value)} value={email} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Phone</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setPhone(e.target.value)} value={phone} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Description</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setDescription(e.target.value)} value={description} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Categories</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setCategories(e.target.value)} value={categories} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Areas</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setAreas(e.target.value)} value={areas} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Event</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setEvent(e.target.value)} value={event} />
</div>
<button type='submit' className='btn btn-success mt-5' style={{ marginRight: 5 + 'px' }} name='edit'>Submit</button>
<button className='btn btn-secondary mt-5' onClick={sendToHome}>Cancel</button>
</form>
);
};
export default EditContact;
If someone knows how to resolve this problem, I'll be grateful.

How to add email validation to below code?

The below code is using cards to show account creation, deposit and other module.
I need to refractor the code to add email, name, and password field validation, but I am not able to do it.
context.js
const Route = ReactRouterDOM.Route;
const Link = ReactRouterDOM.Link;
const HashRouter = ReactRouterDOM.HashRouter;
const UserContext = React.createContext(null);
function Card(props){
function classes(){
const bg = props.bgcolor ? ' bg-' + props.bgcolor : ' ';
const txt = props.txtcolor ? ' text-' + props.txtcolor: ' text-white';
return 'card mb-3 ' + bg + txt;
}
return (
<div className={classes()} style={{maxWidth: "18rem"}}>
<div className="card-header">{props.header}</div>
<div className="card-body">
{props.title && (<h5 className="card-title">{props.title}</h5>)}
{props.text && (<p className="card-text">{props.text}</p>)}
{props.body}
{props.status && (<div id='createStatus'>{props.status}</div>)}
</div>
</div>
);
}
function CardForm(props) {
const ctx = React.useContext(UserContext);
return (
<>
<div style={{maxWidth: "18rem"}}>
<div className="name-field" style={{display: props.showName}}>
Name<br/>
<input type="input"
id="txtName"
className="form-control"
placeholder="Enter name"
onChange={e => ctx.name=e.currentTarget.value} /><br/>
</div>
<div className="email-field" style={{display: props.showEmail}}>
Email address<br/>
<input type="input"
id="txtEmail"
className="form-control"
placeholder="Enter email"
onChange={e => ctx.email=e.currentTarget.value}/><br/>
</div>
<div className="password-field" style={{display: props.showPassword}}>
Password<br/>
<input type="password"
id="txtPassword"
className="form-control"
placeholder="Enter password"
onChange={e => ctx.password=e.currentTarget.value}/><br/>
</div>
<div className="amount-field" style={{display: props.showAmount}}>
Amount<br/>
<input type="number"
className="form-control"
placeholder="Enter amount"
onChange={e => ctx.balance=e.currentTarget.value}/><br/>
</div>
</div>
</>
)
}
creatAccount.js
function CreateAccount(props){
const [show, setShow] = React.useState(true);
const [status, setStatus] = React.useState('');
const ctx = React.useContext(UserContext);
function addUser() {
ctx.balance = '0';
fetch(`/account/find/${ctx.email}`)
.then(response => response.json())
.then(data => {
console.log(data);
if (data.length===0) ctx.user = true;
})
.then(() => {
if (ctx.user===true) {
const url = `/account/create/${ctx.name}/${ctx.email}/${ctx.password}/${ctx.balance}`;
(async () => {
var res = await fetch(url);
var data = await res.json();
console.log(data);
})();
ctx.user='';
setShow(false);
} else {
ctx.user='';
setStatus('User already exists with that email');
setTimeout(() => setStatus(''),3000);
}})
}
return (
<Card
bgcolor="primary"
header="Create Account"
text=""
status={status}
body={
<>
{show ?
<>
<CardForm setShow={setShow} showAmount="none"/>
{<button type="submit" className="btn btn-light" onClick={addUser}>Create Account</button>}
</>
:
<Success setShow={setShow}/>}
</>
}
/>
);
}
function Success(props) {
return (
<>
<h5>Success!</h5><br/>
<button type="submit"
className="btn btn-light"
onClick={() => props.setShow(true)}>Add another account</button>
</>
)
}
I have tried multiple solutions from online content, but they do not solve the problem.
Lets simplify this
Using NPM package email-validator
Install via NPM
npm install email-validator
import * as EmailValidator from 'email-validator';
Bind your local state to your input field e.g
const [email, setEmail] = useState("");
const [valid, setIsValid] = useState(false);
<input
type="text"
name="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
Create a function to check for email validation like below
const validateEmail = (email) => {
setIsValid(EmailValidator.validate(email));
};
Now there comes two cases. One is to show the validation on change the input field or check on submitting the whole form. To give the validation message while inputting email, you have to use the useEffect hook just like below
useEffect(() => {
if (email) {
validateEmail(email);
}
}, [email, validateEmail]);
You can use the valid state for validation message while user is entering the email something like below
<span>{valid ? 'Email format valid' : 'Invalid email format'} <span>
Second Case
just call the function we created above for email validation and check the valid state.

Can't verify email and password from Firebase

I'm creating a signup form and trying to get the email and password to work. When I used input and set the state with the appropriate values, it works just fine, but once I wrap the Input around my custom component its unable to get data from the component into the state and gives me an error that a user cannot be found (even if their info is in the Firebase Auth)
I need help.
Auth.js
import style from "./auth.module.css";
import { useEffect, useRef, useState } from "react";
import { useAuthState } from 'react-firebase-hooks/auth';
import { auth, signInWithEmailAndPassword, signInWithGoogle } from "../../firebase";
import { CSSTransition } from "react-transition-group";
export default function Auth() {
const [activeMenu, setActiveMenu] = useState("main");
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [user, loading, error] = useAuthState(auth);
let domNode = useClickOutside(() => {
setActiveMenu(false);
});
return (
<div className={style.container}>
<Login />
<Signup />
</div>
);
function AuthType(props) {
return (
<a
href={props.link}
className={style.menuItem}
onClick={() => props.goToMenu && setActiveMenu(props.goToMenu)}
>
{props.children}
</a>
);
}
/* I believe you've switched up the login and sign-up? */
function Login() {
return (
<CSSTransition in={activeMenu === "main"} unmountOnExit timeout={500}>
<div ref={domNode}>
<div className={style.login}>
<h1 className={style.title}>Clip It</h1>
{/* Email and Password */}
<Emailform
label="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<Passform
label="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<div className={style.button}>
<input
type="submit"
value="Login"
onClick={() => signInWithEmailAndPassword(email, password)} />
<input
type="submit"
value="Login with Google"
onClick={signInWithGoogle} />
</div>
<div className={style.text}>
<p className={style.plink}>Forgot Password</p>
<div>
Need an account?
<AuthType goToMenu="Signup">click here</AuthType>
</div>
</div>
</div>
</div>
</CSSTransition>
);
}
function Signup() {
return (
<CSSTransition in={activeMenu === "Signup"} unmountOnExit timeout={500}>
<div ref={domNode}>
<div className={style.signUp}>
<div className={style.title}> Clip It</div>
<Form label="First Name" type="text" />
<Form label="Last Name" type="Text" />
<Form label="Email" type="email" />
<Form label="Date of Birth" type="date" />
<Form label="Password" type="password" />
<Form label="Confirm Password" type="password" />
<div className={style.button}>
<input type="submit" value="Sign Up" />
</div>
<div className={style.text}>
have an
<AuthType goToMenu="main"> account</AuthType>
</div>
</div>
</div>
</CSSTransition>
);
}
}
let useClickOutside = (handler) => {
let domNode = useRef();
useEffect(() => {
let clickListener = (event) => {
if (domNode.current && !domNode.current.contains(event.target)) {
handler();
}
};
document.addEventListener("mousedown", clickListener);
return () => {
document.removeEventListener("mousedown", clickListener);
};
});
return domNode;
};
function Form(props) {
return (
<div className={style.formBox}>
<label className={style.label}>{props.label}:</label>
<form className={style.input}>
<input
type={props.input}
name={props.input}
required="true" />
</form>
</div>
);
}
function Emailform(props) {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
return (
<div className={style.formBox}>
<label className={style.label}>{props.label}:</label>
<form className={style.input}>
<input
type="email"
name={props.input}
required="true"
value={email}
onChange={(e) => setEmail(e.target.value)} />
</form>
</div>
);
}
function Passform(props) {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
return (
<div className={style.formBox}>
<label className={style.label}>{props.label}:</label>
<form className={style.input}>
<input
type="text"
name={props.input}
required="true"
value={password}
onChange={(e) => setPassword(e.target.value)} />
</form>
</div>
);
}
Firebase.js
import firebase from 'firebase/app';
//import * as firebase from "firebase/app";
import "firebase/auth"
import "firebase/firestore"
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: "AIzaSyCq8BAlTWJXG7rFU95QkUTU8U0kXruPA9o",
authDomain: "clip-it-70ff5.firebaseapp.com",
databaseURL: "https://clip-it-70ff5-default-rtdb.firebaseio.com",
projectId: "clip-it-70ff5",
storageBucket: "clip-it-70ff5.appspot.com",
messagingSenderId: "637963668511",
appId: "1:637963668511:web:9cbd1deae03b819153d92a",
measurementId: "G-8S1G78ZH49"
};
const app = !firebase.apps.length ? firebase.initializeApp(firebaseConfig) : firebase.app();
const auth = app.auth();
const db = app.firestore();
/* Using Google Authentication */
const googleProvider = new firebase.auth.GoogleAuthProvider();
//
const signInWithGoogle = async () => {
try {
const res = await auth.signInWithPopup(googleProvider);
const user = res.user;
const query = await db
.collection("users")
.where("uid", "==", user.uid)
.get();
if (query.docs.length === 0) {
await db.collection("users").add({
uid: user.uid,
name: user.displayName,
authProvider: "google",
email: user.email,
});
alert("You're logged in");
}
} catch (err) {
console.error(err);
alert(err.message);
}
};
/* Using Email and Password */
// Sign/Logging In
const signInWithEmailAndPassword = async (email, password) => {
try {
await auth.signInWithEmailAndPassword(email.trim(), password);
alert("You've logged in successfuly");
} catch (err) {
console.error(err);
alert("The email or password is incorrect, please try again");
}
};
//SigningUp
const registerWithEmailAndPassword = async (name, email, password) => {
try {
const res = await auth.createUserWithEmailAndPassword(email.trim(), password);
const user = res.user;
await db.collection("users").add({
uid: user.uid,
name,
authProvider: "local",
email,
});
} catch (err) {
console.error(err);
alert(err.message);
}
};
//Sending Password reset link
const sendPasswordResetEmail = async (email) => {
try {
await auth.sendPasswordResetEmail(email);
alert("Password reset link sent!");
} catch (err) {
console.error(err);
alert(err.message);
}
};
const logout = () => {
auth.signOut();
}; // Log out
export {
signInWithGoogle,
signInWithEmailAndPassword,
registerWithEmailAndPassword,
sendPasswordResetEmail,
logout,
auth,
db,
};
Your code has a list of issues.
You have email/password states in both EmailForm/PassForm, as well as the parent (Auth) component.
You're setting values and trying to handle onChange on the EmailForm/PassForm components, but you never actually call these props, and you never actually set some of the props you're trying to access (ex: name={props.input}).
The inputs inside those two components are setting the email/password states to themselves, yet your Auth component is feeding Firebase its own states for email/password, which you never actually set.
You should also never use an input of type="text" for password fields.
If you insist on keeping the structure you currently have, move the EmailForm and PassForm functions inside to your Auth component, remove the props you're setting onto them, remove their states, and just use the Auth component's state.
// Inside the Auth component
const EmailForm = () => {
return (
<div className={style.formBox}>
<label className={style.label}>{props.label}:</label>
<form className={style.input}>
<input
type="email"
name="email"
required="true"
value={email}
onChange={(e) => setEmail(e.target.value)} />
</form>
</div>
);
}
const PassForm = () => {
return (
<div className={style.formBox}>
<label className={style.label}>{props.label}:</label>
<form className={style.input}>
<input
type="password"
name="password"
required="true"
value={password}
onChange={(e) => setPassword(e.target.value)} />
</form>
</div>
);
}
Then call them with a simple
<EmailForm />
<PassForm />

React - how to use map to pass an array of options on input of type unform select

I have a select input where I want to pass an options array object using map but when rendering my page only one option even when the array I'm using in the map has several items it insists on presenting only one
below all the code:
export default function PesquisarAulas() {
const dispatch = useDispatch();
const user = useSelector((state) => state.user.profile);
const [docente, setDocente] = useState([]);
const [docenteDisciplinas, setDocenteDisciplinas] = useState([]);
const [disciplinas, setDisciplinas] = useState([]);
const updateDisciplinas = [...disciplinas];
async function carregarDocente() {
const response = await api.get(`docente/findByUser/${user.id}`);
return response.data;
}
async function carregarDisciplinasDocente() {
const response = await api.get(`docente/${docente.id}/disciplinas`);
return response.data;
}
async function carregarDisciplina(disc) {
const response = await api.get(`disciplinas/${disc.id_disciplina}`);
return response.data;
}
useEffect(() => {
carregarDocente().then((value) => {
setDocente(value);
});
}, [user]);
useEffect(() => {
carregarDisciplinasDocente().then((value) => {
setDocenteDisciplinas(value);
});
}, [docente]);
useEffect(() => {
docenteDisciplinas.map((docDisc) =>
carregarDisciplina(docDisc).then((value) => {
updateDisciplinas.push(value);
setDisciplinas(updateDisciplinas);
})
);
}, [docenteDisciplinas]);
console.log(disciplinas);
function handleSubmit() {}
return (
<Container>
<div className="title">Pesquisar aulas</div>
<Form onSubmit={handleSubmit}>
<div className="input-box">
<span>Ano Letivo:</span>
<Input
name="anoLetivo1"
type="text"
placeholder="Introduza o ano letivo"
/>
</div>
<div className="input-box">
<span>Disciplinas:</span>
<Select
name="tech"
options={disciplinas.map((disciplina) => ({
id: disciplina.id,
title: disciplina.nome,
}))}
placeholder="Nenhum selecionado"
/>
</div>
<div className="input-box">
<span>Aulas de:</span>
<Input name="dataInicio1" type="datetime-local" id="pickup_time" />
<span style={{ marginLeft: '10px' }}>ate:</span>
<Input name="dataFinal1" type="datetime-local" id="pickup_time" />
</div>
<div className="input-box">
<span>Curso:</span>
<Input name="curso1" type="text" placeholder="Introduza o curso" />
</div>
<div className="input-box">
<span>Unidade Curricular:</span>
<Input
name="unidadeCurricular1"
type="text"
placeholder="Introduza a unidade curricular"
/>
</div>
<hr />
<button type="submit">Pesquisar</button>
</Form>
</Container>
);
}
the focus of the problem is on these two code snippets here:
const [disciplinas, setDisciplinas] = useState([]);
const updateDisciplinas = [...disciplinas];
useEffect(() => {
docenteDisciplinas.map((docDisc) =>
carregarDisciplina(docDisc).then((value) => {
updateDisciplinas.push(value);
setDisciplinas(updateDisciplinas);
})
);
}, [docenteDisciplinas]);
<Select
name="tech"
options={disciplinas.map((disciplina) => ({
id: disciplina.id,
title: disciplina.nome,
}))}
placeholder="Nenhum selecionado"
/>
I think the problem is that when the select is rendered only one item is inserted in the disciplines array,
I think maybe if there was a way to make Select wait until all the items in the disciplines array are ready so it can render, the problem would be solved.
Try using the select like this:
<select placeholder="Nenhum selecionado" >
{{disciplinas.map((disciplina) => {
<option value={disciplina.nome}>
{disciplina.nome}
</option>
})}}
</select>

Can't send uploaded image url from firebase into another components in react hooks

I can't send uploaded image url from firebase storage into another component using react hooks , can anybody help me? I'm new to the react and working on this part of code about 2 weeks and did'nt have any progress, it really annoying me.
This is main component where images url should come in order to render it
import React, { useState, useEffect} from "react";
import firebase from "firebase";
import Uploader from "./uploader";
function EditorBlog() {
const [title, setTitle] = useState("");
const [text, setText] = useState("");
const [category, setCategory] = useState("");
const [url , setUrl]= useState("");
const [items, setItems] = useState([]);
const onSubmit = (data) => {
data.preventDefault();
setItems([...items, {title, text, category , url} ]);
firebase
.firestore()
.collection('blogContent')
.add({
title,
category,
text,
url
// file
})
.then(()=>{
setTitle('')
setCategory('')
setText('')
setUrl('')
});
};
return (
<div>
<form onSubmit={onSubmit} className="col-md-6 mx-auto mt-5">
<div className="form-group">
<label htmlFor="Title">Blog Title</label>
<input
type="text"
name="title"
value={title}
onChange={(e) => setTitle(e.target.value)}
className="form-control"
id="Title"
placeholder="Arnold Schwarzneiger"
/>
</div>
<Uploader/>
<div className="form-group">
<label htmlFor="categorySelect">Select Category</label>
<select className="form-control" value={category} onChange={e => setCategory(e.target.value)} name="category" id="categorySelect">
<option>Nutrition</option>
<option>Fitness</option>
<option>Recipes</option>
<option>Succesfull Stories</option>
<option>Other</option>
</select>
</div>
<div className="form-group">
<label htmlFor="blogText">Blog Text</label>
<textarea
className="form-control"
name="text"
id="blogText"
rows="3"
value={text}
onChange={(e) => setText(e.target.value)}
></textarea>
</div>
<button
type="submit"
className="btn btn-primary offset-5"
onClick={onSubmit}
>
Save
</button>
</form>
<div className="mt-5">
{
items.map((item, index) => (
<div className="row bg-dark mx-auto ">
<div key={item.id} className="col-md-6 blogs_content mx-auto mt-5 " >
<div className="mblog_imgtop "><p>Beginner</p></div>
<img className="img-fluid editor_img " src={item.url} alt=""/>
<div className="col-md-12 rblog_txt text-center mx-auto">
<h6 className="mblog_category mx-auto m-4">{item.category}</h6>
<h2 className="blogs_title col-md-10 mx-auto">{item.title}</h2>
<div className="mt-5 mblog_innertxt col-md-11 mx-auto">{item.text}</div>
<div className="readm mt-5"><i>READ MORE</i></div>
</div>
</div>
</div>
))
}
</div>
</div>
);
}
export default EditorBlog;
this is my second component in which uploaded image url must be send into main component
import React, {useState} from "react";
import {storage} from "../../firebaseConfig";
import firebase from "firebase";
export default function Uploader() {
const [image , setImage]= useState(null);
const [url , setURL]= useState("");
const [imgURL, setImgURL] = useState('');
const [progress , setProgress]= useState(0);
const [error , setError]= useState("");
const handleChange =e =>{
const file = e.target.files[0];
if (file){
const fileType= file["type"];
const validFileType= ["image/gif", "image/png", "image/jpg", "image/jpeg"];
if (validFileType.includes(fileType)){
setError("");
setImage(file);
}else setError("Siz rasm kiritmadingiz");
}else {
setError("Iltimos faylni tanlang");
}
};
const handleUpload = props=>{
if (image){
const uploadTask =storage.ref(`images/${image.name}`).put(image);
uploadTask.on(
"state_changed",
snapshot =>{
const progress = Math.round(
(snapshot.bytesTransferred/snapshot.totalBytes)*100
);
setProgress(progress);
},
error =>{
setError(error);
},
()=>{
storage.ref("images").child(image.name).getDownloadURL().then(url=>{
setURL(url);
console.log(url);
firebase
.firestore()
.collection('images')
.add({
url
})
.then(()=>{
setURL('')
});
setProgress(0);
});
}
)
}else setError("Xatolik Iltimos rasmni yuklang")
};
return(
<div>
<form >
<div className="form-group" >
<input type="file" className="form-control" onChange={handleChange} />
<button type="button" className="btn btn-primary btn-block" onClick={handleUpload}>Upload</button>
</div>
</form >
<div>
{progress > 0 ? <progress style={{marginLeft: "15px"}} value={progress} max="100"/> :""}
</div>
<div style={{height : "100px", marginLeft: "15px", fontWeight: "600"}}>
<p style={{color: "red"}}>{error}</p>
</div>
<img src={url || 'http://via.placeholder.com/400x300'} alt="Uploaded images" height="300" width="650"/>
</div>
)
}
Using a callback, your EditorBlog component can tell the Uploader component what to do when an upload is complete.
In other words, EditorBlog passes a function called "onComplete" as a prop to Uploader. When the upload is completed, Uploader calls this function, with the URL as an argument.
EditorBlog
export default function EditorBlog() {
const [url , setUrl] = useState(null);
// ...
const handleCompletedUpload = (url) => {
setUrl(url);
}
return (
// ...
<div>
<Uploader onComplete={handleCompletedUpload} />
<img src={url || 'http://via.placeholder.com/400x300'} alt="Uploaded images" height="300" width="650" />
</div>
// ...
);
}
Uploader:
export default function Uploader({ onComplete }) {
// ...
uploadTask.on(
"state_changed", (snapshot) => {
// ... progress update
},
(error) => {
// ... error
},
() => {
// Success. Get the URL and call the prop onComplete
uploadTask.snapshot.ref.getDownloadURL().then(url => {
onComplete(url); // Call the callback provided as a prop
});
})
// ...
}
By the way: Notice how you can get the file reference from the uploadTask directly: uploadTask.snapshot.ref.getDownloadURL(). This way you don't have to create a new reference manually, like storage.ref("images").child(image.name).getDownloadURL().

Resources