I had previously tried using django for this project but switched to reactjs but encountering some similar problems. The data isn't being uploaded to real time database or to storage. The page doesn't navigate with the navigate function placed after the firebase upload
import firebase from "firebase/compat/app";
import { useNavigate } from "react-router-dom";
import "firebase/compat/database";
import "firebase/compat/storage";
const AddRestaurant = () => {
const [name, setName] = useState("");
const [city, setCity] = useState("");
const [location, setLocation] = useState("");
const [phone, setPhone] = useState("");
const [website, setWebsite] = useState("");
const [image, setImage] = useState(null);
//const [url, setUrl] = useState("");
const navigate = useNavigate();
const handleSubmit = async (e) => {
e.preventDefault();
const storageRef = firebase.storage().ref();
const imageRef = storageRef.child(`images/${image.name}.jpg`);
await imageRef.put(image);
const imageUrl = await imageRef.getDownloadURL();
firebase.database().ref("Restaurant").push({
name,
city,
location,
phone,
website,
imageUrl,
});
navigate("/restaurants");
};
return (
<form onSubmit={handleSubmit}>
<div className="center">
<input
type="text"
placeholder="Name"
value={name}
onChange={(e) => setName(e.target.value)}
className="border-2 border-gray-300 rounded-md p-2 w-full"
/>
</div>
<div className="center">
<input
type="text"
placeholder="City"
value={city}
onChange={(e) => setCity(e.target.value)}
className="border-2 border-gray-300 rounded-md p-2 w-full"
/>
</div>
<div className="center">
<input
type="text"
placeholder="Location"
value={location}
onChange={(e) => setLocation(e.target.value)}
className="border-2 border-gray-300 rounded-md p-2 w-full"
/>
</div>
<div className="center">
<input
type="text"
placeholder="Phone"
value={phone}
onChange={(e) => setPhone(e.target.value)}
className="border-2 border-gray-300 rounded-md p-2 w-full"
/>
</div>
<div className="center">
<input
type="text"
placeholder="Website"
value={website}
onChange={(e) => setWebsite(e.target.value)}
className="border-2 border-gray-300 rounded-md p-2 w-full"
/>
</div>
<div className="center">
<input type="file" onChange={(e) => setImage(e.target.files[0])} />
</div>
<div className="center">
<button
type="submit"
className="bg-blue-500 text-white rounded-md p-2 w-full"
>
Add Restaurant
</button>
</div>
</form>
);
};
export default AddRestaurant;
I placed the navigate function after the handlesubmit is initiated and it navigated to the next page but no save in the db. Also I would like to add functionality to update restaurant details by name after reading said name from db. Is it wiser to use firestore for this?
Writing to the database (and pretty any call to a cloud API) is an asynchronous operation, as it may take some time to complete. But before that write operation completes, your code already navigates to the next page.
To solve this, wait for the database write to complete, and only then navigate to the next page:
await firebase.database().ref("Restaurant").push({
name,
city,
location,
phone,
website,
imageUrl,
});
navigate("/restaurants");
Related
So I'm working on a booking system project and I have a form that the user can fill out, with a date picker using react-datepicker and a dropdown menu with times that the users can select from. These times are fetched from a firestore database. The times collection looks like this:
times collection in firestore database. And the form information collection looks like this: form-info collection in firestore database.
So when a person selects a time for a specific date, I want to remove that time from the database only for that specific date so that users can still book that same time for another date. Here is what my code looks like:
function GThirtyminsp() {
// Form values
const [date, setDate] = useState(null);
const [email, setEmail] = useState("");
const [name, setName] = useState("");
const [age, setAge] = useState("");
const [team, setTeam] = useState("");
const [number, setNumber] = useState("");
const [time, setTime] = useState(null);
// To show times on screen
const [times, setTimes] = useState([]);
const timesRef = collection(db, "30min-goalie-semiprivate-times");
const formRef = collection(db, "30min-goalie-semiprivate");
useEffect(() => {
const fetchData = async () => {
const timeData = await getDocs(timesRef);
setTimes(timeData.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
};
fetchData();
}, []);
const createBooking = async () => {
await addDoc(formRef, {
name: name,
date: date,
email: email,
number: number,
team: team,
age: age,
time: time,
});
};
const handleSubmit = (e) => {
e.preventDefault();
createBooking();
setName("");
setEmail("");
setDate(null);
setNumber("");
setTeam("");
setTime(null);
setAge("");
};
return (
<div>
<h1 class="text-3xl w-full text-center pt-10 font-bold">
Book 30min Semi-Private Goalie Clinic
</h1>
<div class="flex flex-col items-center">
<form onSubmit={handleSubmit} class="flex flex-col pt-10 w-3/4">
<input
type="text"
name="name"
placeholder="Name"
value={name}
onChange={(e) => setName(e.target.value)}
class="border-2 p-3 mb-5 border-gray rounded-lg"
/>
<input
type="text"
name="email"
placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
class="border-2 p-3 mb-5 border-gray rounded-lg"
/>
<input
type="text"
name="number"
placeholder="Phone Number"
value={number}
onChange={(e) => setNumber(e.target.value)}
class="border-2 p-3 mb-5 border-gray rounded-lg"
/>
<input
type="text"
name="team"
placeholder="Team Name"
value={team}
onChange={(e) => setTeam(e.target.value)}
class="border-2 p-3 mb-5 border-gray rounded-lg"
/>
<input
type="text"
name="age"
placeholder="Age"
value={age}
onChange={(e) => setAge(e.target.value)}
class="border-2 p-3 mb-5 border-gray rounded-lg"
/>
<h2 class="text-center text-xl py-5 font-bold">
Pick a Date and Time
</h2>
<div class="pb-10">
<DatePicker
className="border-2 p-3 w-full border-gray rounded-lg"
selected={date}
onChange={(date) => setDate(date)}
placeholderText="Select a Date"
/>
<div class="pt-10">
<select onChange={(e) => setTime(e.target.value)}>
{times.map((item) => {
return (
<option key={item} value={item.time}>
{item.time}
</option>
);
})}
</select>
</div>
</div>
<button
type="submit"
class="bg-accent text-white font-semibold p-3 rounded-full"
>
Submit
</button>
</form>
</div>
</div>
);
}
You can create a function that when the time is successfully booked, the time document gets deleted from the firebase firestore.
You can await the createBooking and if successful you then call the deletedoc, using the time state as the reference.
https://firebase.google.com/docs/firestore/manage-data/delete-data
Just make sure to validate that the booking was/is successful. Once you have this in-place you will want to reverse the process and add the doc if someone wants to cancel the booking.
Edit: example.
Const deleted= (time) =>{ await deleteDoc(doc(db, "30minute-inprivate etc", (time)
));
}
I am trying to have it so that the background of my weather app will change based on the weather condition using nextjs and the current weather data API. But no image is display. This is my Main
import axios from "axios";
import { useState } from "react";
import Weather from "./Weather";
import Spinner from "./Spinner";
import { data } from "autoprefixer";
import Background from "./Background";
const Main = () => {
const [city, setCity] = useState("");
const [weather, setWeather] = useState({});
const [loading, setLoading] = useState(false);
//In celsius -(&units=metric) in fahrenheit -(&units=imperial)
const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${process.env.NEXT_PUBLIC_WEATHER_KEY}`;
const fetchWeather = (e) => {
e.preventDefault();
setLoading(true);
axios.get(url).then((response) => {
setWeather(response.data);
// console.log(response.data);
});
setCity("");
setLoading(false);
};
if (loading) {
return <Spinner />;
} else {
return (
<div>
{/* Overlay, so we use a self-closing div */}
<div className="absolute top-0 left-0 right-0 bottom-0 bg-black/40 z-[1]" />
<Background
weatherDescription={data.weather ? data.weather[0].main : null}
/>
<div className="relative flex justify-between items-center max-w-[500px] w-full m-auto pt-4 text-white z-10">
<form
onSubmit={fetchWeather}
className="flex justify-between items-center w-full m-auto p-3 bg-transparent border border-gray-300 text-white rounded-2xl"
>
<div>
<input
onChange={(e) => setCity(e.target.value)}
className="bg-transparent border-none text-white focus:outline-none text-2xl"
type="text"
placeholder="Search"
/>
</div>
<button onClick={fetchWeather}>
<BsSearch size={20} />
</button>
</form>
</div>
{weather.main && <Weather data={weather} />}
</div>
);
}
};
And this is the background component
import React from "react";
import img1 from "../public/assets/Rainy weather.jpg";
import img2 from "../imgs/Cloudy Weather.jpg";
function Background(props) {
const images = [
{
name: "Rain",
background: img1,
},
{
name: "Clouds",
background: img2,
},
];
const imgURL = images.find((el) => el.name === props.weatherDescription)
?.background;
return (
<div className="-z-10">
<img
src={imgURL}
className="object-cover w-full min-h-scren"
key={imgURL}
/>
</div>
);
}
export default Background;
I've tried if statements and functions, but nothing is working, I've found this current template that was working with videos, I've tried to change it to use images, but I can't achieve it. I'm fairly new in coding, so I hope someone can help me.
I'm trying to upload a photo in my server folder but when I try to submit it, it doesn't show any picture. It is successfully adding to my database but the picture that I'm trying to upload doesn't show up on my server folder. I'm using React JS as my frontend and I don't get why it is not working. I'm a beginner and I don't know if I'm doing it right. Below is my code.
Multer Code
const path = require('path');
const multer = require('multer');
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, '../Bicycles')
},
filename: (req, file, cb) => {
console.log(file);
cb(null,file.fieldname + "-" + Date.now() + path.extname(file.originalname));
}
})
const upload = multer({ storage: storage }).single("image");
module.exports = upload;
admin route
const router = express.Router();
const upload = require('../Middlewares/uploadMiddleware');
const adminController = require('../controllers/adminController');
const { validateToken } = require('../Middlewares/authAdminMiddleware');
router.get('/admin/auth',validateToken,adminController.adminAuth_get);
router.get('/admins', adminController.admin_get);
router.post('/admin/register',adminController.admin_register);
router.post('/admin/login',adminController.admin_login);
router.get('/admin/logout',adminController.admin_logout);
router.post('/admin/addproduct',upload,adminController.admin_addproduct);
module.exports = router;
Adding product controller
const admin_addproduct = (req, res) => {
const { image, brand, item, quantity, description } = req.body;
Product.create({
image,
brand,
item,
quantity,
description
})
.then((product) => {
res.status(200).json({ product, success: 'Successfully added!' })
})
.catch((err) => console.log(err))
}
React JS frontend
import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
import { AiOutlineLeft } from 'react-icons/ai';
import { FiPlus } from 'react-icons/fi';
import LogoutModal from '../modals/LogoutModal';
import Axios from 'axios';
import { useState } from 'react';
const AddProduct = ({ date,logoutMssg }) => {
const [image,setImage] = useState('');
const [brand,setBrand] = useState('');
const [item,setItem] = useState('');
const [quantity,setQuantity] = useState('');
const [description,setDescription] = useState('');
const [showImage,setShowImage] = useState(false);
const [imageHolder,setImageHolder] = useState('');
const onSubmit = (e) => {
e.preventDefault();
const formData = new FormData();
formData.append("image", image);
formData.append("brand",brand);
formData.append("item",item);
formData.append("quantity", quantity);
formData.append("description",description);
Axios.post('/api/admin/addproduct',formData)
.then((res) => {
console.log(res);
})
}
// previews image before uploading
const imageHandler = (e) => {
const reader = new FileReader();
reader.onload = () => {
if(reader.readyState === 2) {
setImageHolder(reader.result);
setShowImage(true);
}
}
reader.readAsDataURL(e.target.files[0]);
setImage(e.target.value);
}
return (
<div className="flex justify-center">
<Helmet><title>Bicycle System | Add Products</title></Helmet>
<div className="max-w-7xl w-full">
<div className="flex items-center justify-between py-5">
<Link className="flex items-center text-xl font-semibold" to='/dashboard'><AiOutlineLeft />Go Back</Link>
<label htmlFor="date">{date}</label>
</div>
<form onSubmit={onSubmit} className="px-16 py-14">
<h1 className="text-3xl font-bold p-2 border-b-2 border-gray-300">Add Product</h1>
<div className="py-2 px-2 flex gap-10">
<div className="max-h-60 border p-20 flex items-center justify-center relative bg-gray-50">
<input value={image} name="image" onChange={imageHandler}
className="opacity-0 w-64 h-60 absolute cursor-pointer" type="file" accept="image/*" required/>
{ showImage ?
<img className="object-cover w-64" src={imageHolder} alt="cover" />
:
<label className="flex justify-center items-center flex-col" htmlFor="file">
<FiPlus size="100px" />
Add Photo
</label>
}
</div>
<div className="flex flex-col">
<div className="flex flex-col">
<label htmlFor="brandname">Brand Name</label>
<input className="border border-gray-400 w-60 outline-none" type="text" required
value={brand} onChange={(e) => setBrand(e.target.value)}
/>
</div>
<div className="flex flex-col">
<label htmlFor="brandname">Item Name</label>
<input className="border border-gray-400 w-60 outline-none" type="text" required
value={item} onChange={(e) => setItem(e.target.value)}
/>
</div>
<div className="flex flex-col">
<label htmlFor="brandname">Quantity</label>
<input className="w-28 border border-gray-400 outline-none" type="number" required
value={quantity} onChange={(e) => setQuantity(e.target.value)}
/>
</div>
</div>
<div className="w-full relative">
<div className="flex-col flex">
<label htmlFor="description">Item Description</label>
<textarea className="w-full border border-gray-400 outline-none h-32" id=""
value={description} onChange={(e) => setDescription(e.target.value)}></textarea>
<button className="absolute bottom-5 text-gray-100 p-2 bg-gray-900 rounded-md">Add Product</button>
</div>
</div>
</div>
</form>
</div>
{/* modal when logging out */}
{ logoutMssg && <LogoutModal /> }
</div>
)
}
export default AddProduct
Create a folder- images, in the root directory. Then implement code as follows:
const imageStorage = multer.diskStorage({
// Destination to store image
destination: 'images',
filename: (req, file, cb) => {
cb(null, file.fieldname + '_' + Date.now()
+ path.extname(file.originalname))
// file.fieldname is name of the field (image)
// path.extname get the uploaded file extension
}
});
Destination is used so that the application can know where to store images. It can be a string (e.g. ‘./upload’). The default directory for all the temporary files is used in case the destination is not provided. Creating a directory is compulsory when you use the destination as a function. Or else, if you use destination as string, Multer will create directory.
For some reason upon clicking the submit button on a login form in my React tutorial, the URL changes from domain.com/login to domain.com/login?email=max%40test.com&password=admin123 putting the email and password field into the URL.
The instructor's example doesn't seem to do this.
LoginScreen.js
import { useState } from 'react'
import { Link, useLocation } from 'react-router-dom'
import { useDispatch } from 'react-redux'
import { loginAction } from '../state/actions/userActions'
const LoginScreen = () => {
const [email, setEmail] = useState('')
const [password, setPW] = useState('')
const location = useLocation()
const dispatch = useDispatch()
const submitLoginHandler = (e) => {
e.preventDefault()
dispatch(loginAction(email, password))
}
return (
<div className="full-container w-full">
<div className="login-content-container max-w-5xl mx-auto p-16 my-8">
<div className="login-container flex items-center bg-white shadow-2xl rounded-md overflow-hidden">
<div className="form-container rounded-md p-8 my-16">
<h2 className="my-1 font-medium text-center text-2xl">sevenTwigs</h2>
<span className="mb-8 block text-center font-light text-md">Account Login</span>
<form className="login-form p-4">
<div className="input-group flex flex-col items-center">
<input
className="email-input border-2 border-gray-200 placeholder-gray-400 rounded-md px-4 py-2 m-2 w-full text-sm font-light"
type="email"
name="email"
placeholder="Enter your email"
value={email}
onChange={(e) => setEmail(e.target.value)} />
<input
className="password-input border-2 border-gray-200 placeholder-gray-400 rounded-md px-4 py-2 m-2 w-full text-sm font-light"
type="password"
name="password"
placeholder="Your password"
value={password}
onChange={(e) => setPW(e.target.value)} />
<button
type="submit"
className="w-full rounded-sm px-4 py-2 bg-pink-400 hover:bg-pink-300 hover:shadow-md disabled:bg-gray-400
text-white shadow-sm text-center text-sm my-4"
value="submit"
onClick={(e) => submitLoginHandler(e)} >
LOG IN
</button>
</div>
</form>
<div className="new-user-register text-sm text-center text-gray-400">
Don't have an account?
<Link to="/register/" className="text-gray-500"> Register</Link>
</div>
</div>
<div className="form-splash-image bg-black w-2/3 hidden md:flex">
<img src="/images/wallpainting.jpg" alt="" />
</div>
</div>
</div>
</div>
)
}
export default LoginScreen
app.js
import {BrowserRouter as Router, Route } from 'react-router-dom'
import Header from './components/Header'
import Footer from './components/Footer'
import HomeScreen from './screens/HomeScreen'
import ProductScreen from './screens/ProductScreen'
import CartScreen from './screens/CartScreen'
import CheckoutScreen from './screens/CheckoutScreen'
import LoginScreen from './screens/LoginScreen'
function App() {
return (
<Router>
<Header />
<div className="main-content h-full min-h-screen flex" style={{backgroundColor: '#f5fcf7'}}>
<Route path="/" component={HomeScreen} exact />
<Route path="/products/:id" component={ProductScreen} />
<Route path="/cart" component={CartScreen} />
<Route path="/checkout" component={CheckoutScreen} />
<Route path="/login" component={LoginScreen} />
</div>
<Footer />
</Router>
);
}
export default App;
Backend Express Routes
const express = require('express')
const router = express.Router()
const { userAuth, registerUser, retrieveProfile } = require('../controller/userController')
const { protect } = require('../middleware/authTokenMW')
router.post('/login', userAuth)
router.post('/register', registerUser)
router.route('/profile')
.get(protect, retrieveProfile)
module.exports = router
server.js
const express = require('express')
const dotenv = require('dotenv')
const mongoose = require('mongoose')
const connectDB = require('./config/db')
const products = require ('./data/products')
const productRoutes = require('./routes/productRoutes')
const userRoutes = require('./routes/userRoutes')
const { notFound, errorHandler } = require('./middleware/errorHandlerMW')
const app = express()
dotenv.config()
connectDB()
app.use(express.json())
// Start Server
app.listen(5000, () =>{
console.log('Server started')
})
// Route for Products
app.use('/api/products', productRoutes)
// Route for Users
app.use('/api/users/', userRoutes)
// Error Handlers
app.use(notFound)
app.use(errorHandler)
Is putting text field values into query strings in the URL done by React on default? Or did I mess with something inadvertently?
Your button is of type submit and you have not specified any properties for the form. So by default, it is going to assume a few things,
method="Get" and
action="Your URL"
So it adds all params to your URL as query string params.
And adding the submit event to the form will solve the issue as you have e.preventDefault there.
If you pass event as a parameter on function call, the e.preventDefault() will not work.
Try to use just
onClick={submitLoginHandler}
instead of
onClick={(e) => submitLoginHandler(e)}
I'm new in React and state hooks.I'm trying to make a website about creating booklist and save it to local storage. Also uploading image to cloudinary. My problem is ; when i trying to save cloudinary image url to the localstorage, it saves previous url. I think i have a problem about useState hooks but i couldnt figure it. Below is my code.
LocalStorage.js
import React, { useState, useEffect } from 'react'
import BookList from '../../components/BookList'
import CreateBook from '../../components/CreateBook'
const getLocalStorage = () => {
let list = localStorage.getItem('liste')
if (list) {
return JSON.parse(localStorage.getItem('liste'))
} else {
return []
}
}
const LocalStorage = () => {
//state hooks
const [list, setList] = useState(getLocalStorage)
const [bookName, setBookName] = useState('')
const [writerName, setWriterName] = useState('')
const [pageNumber, setPageNumber] = useState('')
const [info, setInfo] = useState('')
const [image, setImage] = useState('')
const [uploadUrl, setUploadUrl] = useState('')
let id
//Function for submit button
const handleSubmit = async (e) => {
e.preventDefault()
// conditions for fill the blanks
if (!bookName || !writerName || !pageNumber || !image) {
setInfo('Please fill the blanks')
} else {
try {
const data = new FormData()
data.append('file', image)
data.append('upload_preset', 'book-list-project')
data.append('cloud_name', 'book-list')
let response = await fetch(
'https://api.cloudinary.com/v1_1/book-list/image/upload',
{
method: 'POST',
body: data,
}
)
let result = await response.json()
setUploadUrl(result.url)
id = new Date().getTime().toString()
const newBook = {
id: id,
bookName: bookName,
writerName: writerName,
pageNumber: pageNumber,
uploadUrl: uploadUrl,
}
setList([...list, newBook])
setBookName('')
setWriterName('')
setPageNumber('')
setInfo('Book created')
setImage('')
} catch (error) {
console.log(error)
}
}
}
//Function for remove specific book from local storage
const removeSpecificBook = (id) => {
setList(list.filter((book) => book.id !== id))
}
// Function for clear all books from local storage
const removeAllBooks = () => {
setList([])
}
useEffect(() => {
localStorage.setItem('liste', JSON.stringify(list))
}, [list])
return (
<div>
<CreateBook
bookName={bookName}
writerName={writerName}
pageNumber={pageNumber}
handleSubmit={handleSubmit}
info={info}
setBookName={setBookName}
setWriterName={setWriterName}
setPageNumber={setPageNumber}
setImage={setImage}
/>
<BookList
items={list}
removeSpecificBook={removeSpecificBook}
removeAllBooks={removeAllBooks}
/>
</div>
)
}
export default LocalStorage
Booklist.js
import React from 'react'
const BookList = ({ items, removeSpecificBook, removeAllBooks }) => {
return (
<div className='container mx-auto'>
<div className='mt-20 flex flex-wrap items-center justify-center'>
{items.map((item) => {
return (
<div key={item.id} className='p-2 m-2 bg-yellow-100 w-1/4'>
<div className='p-1 m-1 flex justify-center'>
<img
className='object-contain h-52 w-52'
src={item.uploadUrl}
alt='some img'
/>
</div>
<div className='p-1 m-1'>
<h5 className='font-semibold'>Book Name</h5>
<h3>{item.bookName}</h3>
</div>
<div className='p-1 m-1'>
<h5 className='font-semibold'>Writer Name</h5>
<h3>{item.writerName}</h3>
</div>
<div className='p-1 m-1'>
<h5 className='font-semibold'>Total Page</h5>
<h3>{item.pageNumber}</h3>
</div>
<div className='flex justify-end'>
<button
onClick={() => removeSpecificBook(item.id)}
className='px-4 py-2 bg-red-500 rounded-full text-white'
>
Remove
</button>
</div>
</div>
)
})}
</div>
{items.length > 1 && (
<div className='flex justify-center my-5'>
<button
onClick={removeAllBooks}
className='px-8 py-4 bg-red-500 rounded-full text-white'
>
Remove All
</button>
</div>
)}
</div>
)
}
export default BookList
CreateBook.js
import React from 'react'
const CreateBook = ({
bookName,
writerName,
pageNumber,
handleSubmit,
info,
setBookName,
setWriterName,
setPageNumber,
setImage,
}) => {
return (
<div>
<div>
<nav className='bg-blue-500 text-center text-white px-6 py-3'>
Create Book
</nav>
</div>
<div className='bg-red-200 mx-auto w-96 rounded-lg flex justify-center mt-20'>
<form onSubmit={handleSubmit}>
<div>
<div className='p-3 text-center'>
<h6>Enter Book Name</h6>
<input
value={bookName}
onChange={(e) => setBookName(e.target.value)}
className='rounded-md'
type='text'
placeholder='Book Name'
/>
</div>
<div className='p-3 text-center'>
<h6>Enter Writer Name</h6>
<input
value={writerName}
onChange={(e) => setWriterName(e.target.value)}
className='rounded-md'
type='text'
placeholder='Writer Name'
/>
</div>
<div className='p-3 text-center'>
<h6>Enter Total Page Number </h6>
<input
value={pageNumber}
onChange={(e) => setPageNumber(e.target.value)}
className='rounded-md'
type='number'
placeholder='Page Number'
/>
</div>
<div className='p-3 text-center'>
<div>
<h6>Upload Image</h6>
</div>
<div className='p-3'>
<input
type='file'
onChange={(e) => setImage(e.target.files[0])}
/>
</div>
</div>
<div className='flex justify-center p-3'>
<button className='bg-blue-500 py-3 px-6 rounded-full text-white'>
Submit
</button>
</div>
<div className='p-3 text-center text-white'>
<h3>{info}</h3>
</div>
</div>
</form>
</div>
</div>
)
}
export default CreateBook
Also please if you have any suggestions about my code structure, tell me. I dont have any programming history and trying to learn from beginning. I need every suggestions to go further learning programming. Thank you in advance.
setUploadUrl(result.url);
id = new Date().getTime().toString();
const newBook = {
id: id,
bookName: bookName,
writerName: writerName,
pageNumber: pageNumber,
uploadUrl: uploadUrl
};
In here you are updating the uploadUrl to the newBook object. But the value of uploadUrl hold the previous record. Instead of setting from uploadUrl, set it from result.url.