I am trying to add a post in Graphql and storing it in Redis, below is the code:
Client
NewPost.js:
import { useMutation, useQuery } from "#apollo/client";
import { UPLOAD_IMAGE } from "./mutation";
import { useState } from "react";
function NewPost() {
const [posterName, setPosterName] = useState(null);
const [uploadImage] = useMutation(UPLOAD_IMAGE);
const [url, setUrl] = useState(null);
const [description, setDescription] = useState(null);
const addPost = () => {
uploadImage({
variables: {
url: url,
description: description,
posterName: posterName,
},
});
};
return (
<div className="App">
Url--- <input onChange={(e) => setUrl(e.target.value)} />
<br />
PosterName--- <input onChange={(e) => setPosterName(e.target.value)} />
<br />
Description ---
<input onChange={(e) => setDescription(e.target.value)} />
<br />
<button onClick={() => addPost()}>Add Post</button>
</div>
);
}
export default NewPost;
mutation.js:
import { gql } from "#apollo/client";
export const UPLOAD_IMAGE = gql`
mutation uploadImage($url: String, $description: String, $posterName: String) {
uploadImage(post: { url: $url, description: $description , posterName: $posterName }) {
url
posterName
description
}
}
`;
App.js:
import React from 'react';
import {NavLink, BrowserRouter as Router, Route} from 'react-router-dom';
import UserPosts from './components/UserPosts';
import Bin from './components/Bin';
import Home from './components/Home';
import NewPost from './components/NewPost';
import UnsplashPosts from './components/UnsplashPosts';
import {
ApolloClient,
HttpLink,
InMemoryCache,
ApolloProvider
} from '#apollo/client';
const client = new ApolloClient({
cache: new InMemoryCache(),
link: new HttpLink({
uri: 'http://localhost:4000'
})
});
function App() {
return (
<ApolloProvider client={client}>
<Router>
<div>
<header className='App-header'>
<h1 className='App-title'>
GraphQL Lab5
</h1>
<nav>
<NavLink className='navlink' to='/'>
Home
</NavLink>
<NavLink className='navlink' to='/my-bin'>
Bin
</NavLink>
<NavLink className='navlink' to='/my-posts'>
Posts
</NavLink>
<NavLink className='navlink' to='/new-post'>
Create New Post
</NavLink>
</nav>
</header>
<Route exact path='/' component={UnsplashPosts} />
<Route path='/my-bin/' component={Bin} />
<Route path='/my-posts' component={UserPosts} />
<Route path='/new-post' component={NewPost} />
</div>
</Router>
</ApolloProvider>
);
}
export default App;
Server
index.js:
const {ApolloServer, gql} = require('apollo-server');
const axios = require('axios');
const uuid = require('uuid');
const bluebird = require('bluebird');
const redis = require('redis')
const client = redis.createClient();
bluebird.promisifyAll(redis.RedisClient.prototype);
bluebird.promisifyAll(redis.Multi.prototype);
const typeDefs = gql`
type Query {
photos: [Photo]
post: [ImagePost]
unsplashImages: [ImagePost]
userPostedImages: [ImagePost]
}
type Photo {
id: String
username: String
}
type ImagePost {
id: String
url: String!
posterName: String!
description: String
userPosted: Boolean
binned: Boolean
}
type Mutation {
uploadImage(
url: String
description: String
posterName: String
): ImagePost
}
`;
const resolvers = {
Query: {
unsplashImages: async (_, args) => {
const { data } = await axios.get('https://api.unsplash.com/photos/?client_id=2zceQd7D4SraKoqW_GjPzXboSup3TKRIPk7EXfJBcAs');
const a = data.map(imagePost => {
return {
id: imagePost.id,
posterName: imagePost.user.name,
url: imagePost.urls.raw,
description: imagePost.description,
}
})
return a;
},
userPostedImages: async (_,args) => {
let history = await client.lrangeAsync("postedImagesList",0,100).map(JSON.parse);
return history;
}
},
Mutation: {
uploadImage: async (_,args) => {
//const { data } = await axios.get('https://api.unsplash.com/photos/?client_id=2zceQd7D4SraKoqW_GjPzXboSup3TKRIPk7EXfJBcAs');
const newPost = {
id: uuid.v4(),
url: args.url,
description: args.description,
posterName: args.posterName,
binned: false,
userPosted: true,
}
await client.lpushAsync("postedImagesList",JSON.stringify(newPost));
}
}
};
const server = new ApolloServer({typeDefs, resolvers});
server.listen().then(({url}) => {
console.log(`🚀 Server ready at ${url} 🚀`);
});
When I try to add a post only using the server I am able to do so in the playground, but when I click on Add post in frontend, the post does not get added to redis and does not show up.
Related
I have a react application built for production and being served by a node/express server.
I have started the server locally and also deployed it to heroku and render.com
On all these systems, Chrome and Edge have no problems and no errors when accessing the site. But: Firefox won't populate the root element and shows a weird error. Only after refreshing, Firefox shows the site perfectly.
This is the error and the corresponding code ... it doesn't make sense
TypeError: wi.get(...) is undefined
ts Header.jsx:36
React 7
C scheduler.production.min.js:13
T scheduler.production.min.js:14
813 scheduler.production.min.js:14
Webpack 12
react-dom.production.min.js:189:29
React 9
C scheduler.production.min.js:13
T scheduler.production.min.js:14
(Async: EventHandlerNonNull)
813 scheduler.production.min.js:14
Webpack 12
const availableLanguages = [
{
code: "he",
name: "עברית",
country_code: "il",
dir: "rtl",
},
{
code: "en",
name: "English",
country_code: "gb",
},
{
code: "de",
name: "Deutsch",
^---- The error is showing for this code position! There is no code!
country_code: "de",
},
];
This happens on all three environments, tested from three different systems.
Does anyone know what is happening?
EDIT: Full Header.jsx
import { useState, useRef, useEffect } from "react";
import i18next from "i18next";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import useOutsideClick from "../hooks/useOutsideClick";
import useAuth from "../hooks/useAuth";
import Anchor from "./Anchor";
import "./Header.css";
import claryNextLogo from "../images/ClaryNext2.png";
import cookies from "js-cookie";
import { config } from "../Environment";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { solid } from "#fortawesome/fontawesome-svg-core/import.macro";
import { useContext } from "react";
import { WSContext } from "../App";
import { useEffectOnce } from "../hooks/useEffectOnce";
import { distributionService } from "../services/distributionService";
import MessageBox from "./MessageBox";
import useRetryFetch from "../hooks/useRetryFetch";
const availableLanguages = [
{
code: "he",
name: "עברית",
country_code: "il",
dir: "rtl",
},
{
code: "en",
name: "English",
country_code: "gb",
},
{
code: "de",
name: "Deutsch",
country_code: "de",
},
];
function Header() {
const currentLanguageCode = cookies.get("i18next").split("-")[0] || "en";
const currentLanguage = availableLanguages.find(
(l) => l.code === currentLanguageCode
);
const { auth, setAuth } = useAuth();
const navigate = useNavigate();
const dropdownRef = useRef(null);
const retryFetch = useRetryFetch();
const [showLanguageDropdown, setShowLanguageDropdown] = useState(false);
const [showMessageBox, setShowMessageBox] = useState(false);
const [msgBoxTitle, setMsgBoxTitle] = useState("");
const [msgBoxButtons, setMsgBoxButtons] = useState({});
const [msgBoxInputs, setMsgBoxInputs] = useState([]);
const [msgBoxId, setMsgBoxId] = useState("");
const [msgBoxMoreJSX, setMsgBoxMoreJSX] = useState(null);
const [chatRequestUser, setChatRequestUser] = useState("");
const [chatRequestProcessId, setChatRequestProcessId] = useState("");
const [chatRequestRoomId, setChatRequestRoomId] = useState(0);
const { t } = useTranslation();
const { socket } = useContext(WSContext);
const openMessageBox = (title, id, buttons, inputs, moreJSX) => {
setMsgBoxTitle(title);
setMsgBoxId(id);
setMsgBoxButtons(buttons);
setMsgBoxInputs(inputs);
setMsgBoxMoreJSX(moreJSX);
setShowMessageBox(true);
};
const onButton = async (result) => {
console.log("MessageBox button was clicked");
console.dir(result);
if (result.btnId === "yes") {
// chat was accepted, change to ShowFullLog, join room and notify user
socket.send(
JSON.stringify({
command: "acceptchat",
payload: { email: chatRequestUser, roomId: chatRequestRoomId },
})
);
// collect necessary process log information
let response = await retryFetch(
`${config.API_BASE}/api/processes/${chatRequestProcessId}`
);
let process = await response.json();
let stateToPass = {
processId: chatRequestProcessId,
presName: process.prescriptionName,
presHistoryId: process.fiPrescriptionHistory._id,
autochat: true,
};
if (process.fiExpert?.email === auth.email) {
stateToPass.userEmail = process.fiInitiator?.email;
navigate("/fulllog", { state: stateToPass });
} else {
stateToPass.expertEmail = process.fiExpert?.email;
navigate("/userlog", { state: stateToPass });
}
} else {
// chat was refused, send message to requesting user
socket.send(
JSON.stringify({
command: "refusechat",
payload: {
email: chatRequestUser,
roomId: chatRequestRoomId,
},
})
);
}
};
useEffect(() => {
document.body.dir = currentLanguage?.dir || "ltr";
}, [currentLanguage]);
useEffectOnce(() => {
let messageUnsubscribe = distributionService
.getMessage()
.subscribe((msg) => {
console.log("Header incoming message");
switch (msg.command) {
case "requestchat":
setChatRequestUser(msg.payload.email);
setChatRequestProcessId(msg.payload.processId);
setChatRequestRoomId(msg.payload.roomId);
openMessageBox(
t("msg_chat_requested", {
user: msg.payload.email,
processId: msg.payload.processId,
}),
"requestchat",
[
{ id: "yes", text: t("yes") },
{ id: "no", text: t("no") },
],
[],
""
);
break;
}
});
return () => {
// cleanup subscription
messageUnsubscribe.unsubscribe();
};
}, []);
const login = () => {
navigate("/login");
};
const logout = async () => {
let response = await fetch(config.API_BASE + "/logout", {
credentials: "include",
});
if (!response.ok) alert(t("msg_error_logout"));
let result = await response.json();
console.log(result);
setAuth({});
socket.send(
JSON.stringify({
command: "logout",
payload: undefined,
})
);
navigate("/");
};
// const register = () => {
// navigate("/register");
// };
const showPrescriptions = () => {
//navigate("/design");
navigate("/prescriptionlist");
};
const goHome = () => {
navigate("/");
};
const openMenu = () => {
setShowLanguageDropdown(true);
};
const closeMenu = () => {
setShowLanguageDropdown(false);
};
const selectLanguage = (code) => {
i18next.changeLanguage(code);
setShowLanguageDropdown(false);
};
useOutsideClick(dropdownRef, closeMenu);
return (
<>
<div className="header-menu">
<div className="title" onClick={goHome}>
<img src={claryNextLogo} alt="ClaryNext logo" width="90" />
</div>
{!auth?.email ? (
<>
<div className="notonmobile">
<div>
<Anchor
onClick={showPrescriptions}
text={t("example_prescriptions")}
/>
</div>
</div>
<div className="rightflex notonmobile">
<div className="rightMargin">
<span> </span>
</div>
<button onClick={login}>{t("login")}</button>
<span className="leftMargin bigger">
<FontAwesomeIcon
onClick={() => openMenu()}
icon={solid("globe")}
/>
</span>
</div>
</>
) : (
<>
<div className="rightMargin notonmobile">
<Anchor
onClick={showPrescriptions}
text={t("prescriptions_and_processes")}
/>
</div>
<div className="rightflex notonmobile">
<div className="rightMargin">
<Anchor onClick={logout} text={t("logout")} />
</div>
<span className="smaller">{auth.email}</span>
<span className="leftMargin bigger">
<FontAwesomeIcon
onClick={() => openMenu()}
icon={solid("globe")}
/>
</span>
</div>
</>
)}
</div>
{showMessageBox ? (
<MessageBox
onButton={onButton}
buttons={msgBoxButtons}
text={msgBoxTitle}
inputs={msgBoxInputs}
id={msgBoxId}
moreJSX={msgBoxMoreJSX}
onClose={() => setShowMessageBox(false)}
/>
) : (
""
)}
{showLanguageDropdown ? (
<div className="language_dropdown" ref={dropdownRef}>
{availableLanguages.map((lang, idx) => (
<p key={idx} onClick={() => selectLanguage(lang.code)}>
<span
className={`flag-icon flag-icon-${lang.country_code}`}
></span>
{lang.name}
</p>
))}
</div>
) : (
""
)}
</>
);
}
export default Header;
Originally, I had the code to access the cookie in the main function scope. After I moved it into the useEffect[] callback, it started working also in Firefox.
I was working on my first MERN project and was trying to use local storage with context API, but the data is not getting reflected in the local storage and no error is getting reflected either in the console.
When I log in as a user, the local storage still stays empty.
Below is my Context.js code
import { createContext, useEffect, useReducer, useState } from "react";
import Reducer from "./Reducer";
const INITIAL_STATE = {
user: JSON.parse(localStorage.getItem("user")) || null,
isFetching: false,
error: false,
};
export const Context = createContext(INITIAL_STATE);
export const ContextProvider = ({ children }) => {
const [state, dispatch] = useReducer(Reducer, INITIAL_STATE);
const [user, setItems] = useState([]);
useEffect(() => {
localStorage.setItem('user', JSON.stringify(state.user));
}, [state.user]);
return (
<Context.Provider
value={{
user: state.user,
isFetching: state.isFetching,
error: state.error,
dispatch,
}}
>
{children}
</Context.Provider>
);
};
Below is my login.jsx code
import { Link } from "react-router-dom";
import "./login.css"
import { useContext, useRef } from "react";
import axios from "axios";
import { Context } from "../../../context/Context";
export default function Login() {
const userRef = useRef();
const passwordRef = useRef();
const { user, dispatch, isFetching } = useContext(Context);
const handleSubmit = async (e) => {
e.preventDefault();
dispatch({ type: "LOGIN_START" });
try {
const res = await axios.post("/auth/login", {
username: userRef.current.value,
password: passwordRef.current.value,
});
dispatch({ type: "LOGIN_SUCCESS", payload: res.data });
} catch (err) {
dispatch({ type: "LOGIN_FAILURE" });
}
};
console.log(isFetching)
return (
<div className="login">
<span className="loginTitle">Login</span>
<form className="loginForm" onSubmit={handleSubmit}>
<label>Username</label>
<input className="loginInput" type="text" placeholder="Enter your username..." ref=
{userRef} />
<label>Password</label>
<input className="loginInput" type="password" placeholder="Enter your
password..."
ref={passwordRef} />
<button className="loginButton" type="submit">Login</button>
</form>
<button className="loginRegisterButton">
<Link className="link" to="/register">Register</Link>
</button>
</div>
);
}
I have tried googling it out for 2 hours straight, but am not able to get the mistake from which it is arising. Any help is highly appreciated!!
import { createContext, useEffect, useReducer, useState } from "react";
import Reducer from "./Reducer";
const INITIAL_STATE = {
user: JSON.parse(localStorage.getItem("user")) || null,
isFetching: false,
error: false,
};
export const Context = createContext(INITIAL_STATE);
export const ContextProvider = ({ children }) => {
const [state, dispatch] = useReducer(Reducer, INITIAL_STATE);
const [user, setItems] = useState([]);
useEffect(() => {
console.log(state.user);
localStorage.setItem('user', JSON.stringify(state.user));
}, [state.user]);
return (
<Context.Provider
value={{
user: state.user,
isFetching: state.isFetching,
error: state.error,
dispatch,
}}
>
{children}
</Context.Provider>
);
};
I think you'd better check first if user data is in there.
I am trying to display values from an API using apollo client, server, ReactJS and NodeJS, Below is the code to do this:
Client:
UserPosts.js:
import { useMutation, useQuery } from "#apollo/client";
import { USERPostedImages } from "./query";
function UserPosts() {
const { loading, error, data } = useQuery(USERPostedImages);
return (
<div className="App">
{data.userPostedImages.map((data) => (
<>
<p key={data.posterName}>
{data.url}----{data.description}
</p>
</>
))}
</div>
);
}
export default UserPosts;
query.js for the graphql queries:
import { gql } from "#apollo/client";
export const unsplashImages = gql`
{
unsplashImages {
url
posterName
description
}
}
`;
export const USERPostedImages = gql`
{
userPostedImages {
url
posterName
description
}
}
`;
App.js:
import React from 'react';
import {NavLink, BrowserRouter as Router, Route} from 'react-router-dom';
import UserPosts from './components/UserPosts';
import Bin from './components/Bin';
import Home from './components/Home';
import NewPost from './components/NewPost';
import UnsplashPosts from './components/UnsplashPosts';
import {
ApolloClient,
HttpLink,
InMemoryCache,
ApolloProvider
} from '#apollo/client';
const client = new ApolloClient({
cache: new InMemoryCache(),
link: new HttpLink({
uri: 'http://localhost:4000'
})
});
function App() {
return (
<ApolloProvider client={client}>
<Router>
<div>
<header className='App-header'>
<h1 className='App-title'>
GraphQL Lab5
</h1>
<nav>
<NavLink className='navlink' to='/'>
Home
</NavLink>
<NavLink className='navlink' to='/my-bin'>
Bin
</NavLink>
<NavLink className='navlink' to='/my-posts'>
Posts
</NavLink>
<NavLink className='navlink' to='/new-post'>
Create New Post
</NavLink>
</nav>
</header>
<Route exact path='/' component={UnsplashPosts} />
<Route path='/my-bin/' component={Bin} />
<Route path='/my-posts' component={UserPosts} />
<Route path='/new-post' component={NewPost} />
</div>
</Router>
</ApolloProvider>
);
}
export default App;
Server
index.js:
const {ApolloServer, gql} = require('apollo-server');
const axios = require('axios');
const uuid = require('uuid');
const bluebird = require('bluebird');
const redis = require('redis')
const client = redis.createClient();
bluebird.promisifyAll(redis.RedisClient.prototype);
bluebird.promisifyAll(redis.Multi.prototype);
const typeDefs = gql`
type Query {
photos: [Photo]
post: [ImagePost]
unsplashImages: [ImagePost]
userPostedImages: [ImagePost]
}
type Photo {
id: String
username: String
}
type ImagePost {
id: String!
url: String!
posterName: String!
description: String
userPosted: Boolean
binned: Boolean
}
type Mutation {
uploadImage(
url: String!
description: String
posterName: String
): ImagePost
}
`;
const resolvers = {
Query: {
unsplashImages: async (_, args) => {
const { data } = await axios.get('https://api.unsplash.com/photos/?client_id=2zceQd7D4SraKoqW_GjPzXboSup3TKRIPk7EXfJBcAs');
const a = data.map(imagePost => {
return {
id: imagePost.id,
posterName: imagePost.user.name,
url: imagePost.urls.raw,
description: imagePost.description,
}
})
return a;
},
userPostedImages: async (_,args) => {
let history = await client.lrangeAsync("postedImagesList",0,100).map(JSON.parse);
return history;
}
},
Mutation: {
uploadImage: async (_,args) => {
//const { data } = await axios.get('https://api.unsplash.com/photos/?client_id=2zceQd7D4SraKoqW_GjPzXboSup3TKRIPk7EXfJBcAs');
const newPost = {
id: uuid.v4(),
url: args.url,
description: args.description,
posterName: args.posterName,
binned: false,
userPosted: true,
}
await client.lpushAsync("postedImagesList",JSON.stringify(newPost));
}
}
};
const server = new ApolloServer({typeDefs, resolvers});
server.listen().then(({url}) => {
console.log(`🚀 Server ready at ${url} 🚀`);
});
When I run my client I get the below error:
Uncaught TypeError: Cannot read properties of undefined (reading 'userPostedImages')
at UserPosts (UserPosts.js:22:1)
I am not sure what I am doing wrong, my server is working fine and am able to see data in graphql playground but nothing shows up on the client.
data is not available (null) yet because it is still fetching, so to handle this, use conditional rendering with loading value.
const { loading, error, data } = useQuery(USERPostedImages);
if(error) {
return <h1> error</h1>;
}
if(loading) {
return <h1> loading</h1>;
}
....
Mutation on client side of Apollo server:
import { gql } from "#apollo/client";
export const UPLOAD_IMAGE = gql`
mutation uploadImage($url: String!, $description: String!, $posterName: String!) {
uploadImage(post: { url: $url, description: $description , posterName: $posterName }) {
url
posterName
description
}
}
`;
Trying to add new post:
import { useMutation, useQuery } from "#apollo/client";
import { UPLOAD_IMAGE } from "./mutation";
import { useState } from "react";
function NewPost() {
const [posterName, setPosterName] = useState(null);
const [uu, {err}] = useMutation(UPLOAD_IMAGE);
const [url, setUrl] = useState(null);
const [description, setDescription] = useState(null);
const addPost = () => {
uu({
variables: {
url: url,
description: description,
posterName: posterName,
},
});
};
return (
<div className="App">
Url--- <input onChange={(e) => setUrl(e.target.value)} />
<br />
PosterName--- <input onChange={(e) => setPosterName(e.target.value)} />
<br />
Description ---
<input onChange={(e) => setDescription(e.target.value)} />
<br />
<button onClick={() => addPost()}>Add Post</button>
</div>
);
}
export default NewPost;
Mutation on Server side, Apollo server:
Typedef:
type Mutation {
uploadImage(
url: String
description: String
posterName: String
): ImagePost
}
Resolver:
Mutation: {
uploadImage: async (_,args) => {
//const { data } = await axios.get('https://api.unsplash.com/photos/?client_id=2zceQd7D4SraKoqW_GjPzXboSup3TKRIPk7EXfJBcAs');
const newPost = {
id: uuid.v4(),
url: args.url,
description: args.description,
posterName: args.posterName,
binned: false,
userPosted: true,
}
await client.lpushAsync("postedImagesList",JSON.stringify(newPost));
return newPost;
}
}
When a new post is created I am adding it to Redis to store it. But the post does not get added from the input fields and button. It does work using the playground, not sure why. I am retrieving the data using lrangeasync to get back data from Redis.
Try this!
const addPost = async () => {
await uu({
variables: {
post: {
url: url,
description: description,
posterName: posterName,
},
},
});
};
In the bellow example, how can I pass imageAsUrl.imgUrl from the Child component (ImageUpload) to the parent component (UpdateCard).
CHILD Component
import React, { useState, useEffect } from 'react';
import { storage } from '../firebase';
const ImageUpload = () => {
const allInputs = { imgUrl: '' };
const [imageAsUrl, setImageAsUrl] = useState(allInputs);
const [image, setImage] = useState(null);
const handleChange = (e) => {
if (e.target.files[0]) {
setImage(e.target.files[0]);
}
};
useEffect(() => {
if (image) {
const uploadTask = storage.ref(`images/${image.name}`).put(image);
uploadTask.on(
'state_changed',
(snapshot) => {},
(error) => {
console.log(error);
},
() => {
storage
.ref('images')
.child(image.name)
.getDownloadURL()
.then((fireBaseUrl) => {
setImageAsUrl((prevObject) => ({
...prevObject,
imgUrl: fireBaseUrl,
}));
});
}
);
}
}, [image]);
return (
<>
<label className='custom-file-upload'>
<input type='file' onChange={handleChange} />
</label>
<img src={imageAsUrl.imgUrl} alt='sample' />
</>
);
};
export default ImageUpload;
PARENT Component
import React, { useState } from 'react';
import firebase from '../firebase';
import ImageUpload from './ImageUpload';
const UpdateCard = ({ card }) => {
const [originalText, setOriginalText] = useState(card.originalText);
const [translatedText, setTranslatedText] = useState(card.translatedText);
const onUpdate = () => {
const db = firebase.firestore();
db.collection('FlashCards')
.doc(card.id)
.set({ ...card, originalText, translatedText });
timeOutScroll();
};
return (
<>
<div>
{card.imageURL ? (
<img src={card.imageURL} alt='' className='img' />
) : (
<textarea
className='upload-textarea'
value={originalText}
onChange={(e) => {
setOriginalText(e.target.value);
}}
/>
)}
<ImageUpload />
</div>
<textarea
value={translatedText}
onChange={(e) => {
setTranslatedText(e.target.value);
}}
/>
<button onClick={onUpdate}>Update</button>
</>
);
};
export default UpdateCard;
Inside parent,You can define a callback function as prop ref to be called inside the child.
const ImageUpload = ({getURLtoParent}) =>{ <--------------------
const [imageAsUrl, setImageAsUrl] = useState(allInputs);
useEffect(() => {
uploadTask.on(
..............
...
);
if(imageAsUrl.imgUrl !== '')
getURLtoParent(imageAsUrl.imgUrl) <-----------------------
},[image])
}
const UpdateCart = () => {
const[imgURL,setimgURL] = useState(null)
return (
......
<ImageUpload getURLtoParent={ (url) => setimgURL(url) } /> <----------------
.........
)
}