Git Product home page Git Product logo

project_e_commerce's Introduction

E-Commerce

eCommerce

Stay up to date with new projects

New major projects coming soon, subscribe to the mailing list to stay up to date https://javascriptmastery.eo.page/mailing-list.

Introduction

This is a code repository for the corresponding video tutorial.

In this video, we're going to build a fully functional eCommerce application using commerce.js.

While building it you're going to learn many advanced React & JavaScript topics, as well as how to use Stripe for card transactions. On top of that, at the end of the video, you will have this unique and complex webshop app that you will be able to add to your portfolio. And trust me, e-commerce applications are impressive.

project_e_commerce's People

Contributors

adrianhajdin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

project_e_commerce's Issues

Check the render method of `Form`

×
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

I Have got same issue any solution plz?

Refresh cart not working with debit card commerce.js

When you registry a debit card on commerce.js and make the test transaction on final pay the timeout handle works but no email is received and also when you go back to menu the cart is still with products.
Dont know if this is because a debit cart instead of a credit card on commerce.js or because im missing some information on stripe, would like to know, I already review my code and everything looks fine

The given data was invalid

Hi guys i'm creating an e-commerce with CommerceJs and NextJS when handling payment i get this error

message: "The given data was invalid." type: "unprocessable_entity" line_items.item_7RyWOwmK5nEa2V.quantity: ["Requested quantity is not available."]

i tried to change my code like the docs but no luck

Unhandled Rejection (TypeError) ????

I am recieving a type error.

Unhandled Rejection (TypeError): undefined is not an object (evaluating 'options[0].id')
_callee3$
src/Componets/CheckoutForm/AddressForm.jsx:55
52 |
53 | setShippingOptions(options);
54 | console.log(shippingOptions);

55 | setShippingOption(options[0].id);
56 | };
57 |
58 | useEffect(() => {

`import React, { useState, useEffect } from "react";
import {
InputLabel,
Select,
MenuItem,
Button,
Grid,
Typography,
} from "@material-ui/core";
import { useForm, FormProvider } from "react-hook-form";
import { Link } from "react-router-dom";

import FormInput from "../CheckoutForm/CustomTxtField";
import { commerce } from "../../lib/Commerce";

const AddressForm = ({ checkoutToken, test }) => {
const [shippingCountries, setShippingCountries] = useState([]);
const [shippingCountry, setShippingCountry] = useState("");
const [shippingSubdivisions, setShippingSubdivisions] = useState([]);
const [shippingSubdivision, setShippingSubdivision] = useState("");
const [shippingOptions, setShippingOptions] = useState([]);
const [shippingOption, setShippingOption] = useState("");
const methods = useForm();

const fetchShippingCountries = async (checkoutTokenId) => {
const { countries } = await commerce.services.localeListShippingCountries(
checkoutTokenId
);

setShippingCountries(countries);
setShippingCountry(Object.keys(countries)[0]);

};

const fetchSubdivisions = async (countryCode) => {
const { subdivisions } = await commerce.services.localeListSubdivisions(
countryCode
);

setShippingSubdivisions(subdivisions);
setShippingSubdivision(Object.keys(subdivisions)[0]);

};

const fetchShippingOptions = async (
checkoutTokenId,
country,
stateProvince = null
) => {
const options = await commerce.checkout.getShippingOptions(
checkoutTokenId,
{ country, region: stateProvince }
);

setShippingOptions(options);
console.log(shippingOptions);
setShippingOption(options[0].id);

};

useEffect(() => {
fetchShippingCountries(checkoutToken.id);
}, []);

useEffect(() => {
if (shippingCountry) fetchSubdivisions(shippingCountry);
}, [shippingCountry]);

useEffect(() => {
if (shippingSubdivision)
fetchShippingOptions(
checkoutToken.id,
shippingCountry,
shippingSubdivision
);
}, [shippingSubdivision]);

return (



Shipping address

<FormProvider {...methods}>
<form
onSubmit={methods.handleSubmit((data) =>
test({
...data,
shippingCountry,
shippingSubdivision,
shippingOption,
})
)}
>








Shipping Country
<Select
value={shippingCountry}
fullWidth
onChange={(e) => setShippingCountry(e.target.value)}
>
{Object.entries(shippingCountries)
.map(([code, name]) => ({ id: code, label: name }))
.map((item) => (

{item.label}

))}



Shipping Subdivision
<Select
value={shippingSubdivision}
fullWidth
onChange={(e) => setShippingSubdivision(e.target.value)}
>
{Object.entries(shippingSubdivisions)
.map(([code, name]) => ({ id: code, label: name }))
.map((item) => (

{item.label}

))}



Shipping Options
<Select
value={shippingOption}
fullWidth
onChange={(e) => setShippingOption(e.target.value)}
>
{shippingOptions
.map((sO) => ({
id: sO.id,
label: ${sO.description} - (${sO.price.formatted_with_symbol}),
}))
.map((item) => (

{item.label}

))}





<div style={{ display: "flex", justifyContent: "space-between" }}>

Back to Cart


Next





);
};

export default AddressForm;
`

TypeError: Cannot read property 'split' of undefined

Well... I practically copy pasted what you have done but the AddressForm isn't showing up (on the "timeline" in the checkout on the website, it shows at the AddressForm the Payment Details...) so I set the 0 on the line 14 in Checkout.jsx to 1, the Payment Details showed up but after I press the Pay Button, there is the error in the title... I would be glad if anyone can help...

MenuItem and Menu are not defined

import React from 'react';

import { AppBar, Toolbar, IconButton, Badge, MenuItem, Menu, Typography } from '@material-ui/core';

import { ShoppingCart } from '@material-ui/icons';

import { Link, useLocation } from 'react-router-dom'

import logo from '../../assets/Star Image.png';

import useStyles from './styles';

const Navbar = ({ totalItems }) => {

const classes = useStyles();

const location = useLocation();


return (

    <>

        <AppBar position="fixed" className={classes.appBar} color="inherit">

            <Toolbar>

                <Typography component={Link} to="/" variant="h6" className={classes.title} color="inherit">

                    <img src={logo} alt="Commerce.js" height="25px" className={classes.image} />

                    Commerce.js

                </Typography>

                <div className={classes.grow} />
                {location.pathname === '/' && (

                <div className={classes.button}>

                    <IconButton component={Link} to="/cart" aria-label="Show Cart Items" color="inherit">

                        <Badge badgeContent={totalItems} color="Secondary">

                            <ShoppingCart />

                        </Badge>

                    </IconButton>

                </div> )

            }</Toolbar>

        </AppBar>

    </>

)

}

export default Navbar

nvm

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
in AddressForm

TypeError: Cannot read property 'current' of undefined

import React from "react";
import {
InputLabel,
Select,
MenuItem,
Button,
Grid,
Typography,
} from "@material-ui/core";

import FormInput from "./CustomTextField";

import { useForm, FormProvider } from "react-hook-form";

const AddressForm = () => {
const methods = useForm();
return (
<>

Shipping Address

<FormProvider {...methods}>







</>
);
};

export default AddressForm;

Payment Gateway method

Can anybody tell me how can we test confirmation of our order without entering credit card details in commerce js dashboard as just wanted to check my whole app but still giving some error like
image
the sandbox key is not working without stripe integration with commerce js
please help as soon as possible

TypeError: props.render is not a function

Hello, As I was trying this project I faced the following error after checkout
Any ideas on how to fix this please?


25 | try {
  26 |   const token = await commerce.checkout.generateToken(cart.id, { type: 'cart' });
  27 | 
> 28 |   setCheckoutToken(token);
     | ^  29 | } catch {
  30 |   if (activeStep !== steps.length) history.push('/');
  31 | }

Module not found: Can't resolve '@chec/commerce.js'

I started this tutorial and have created my API code and installed the packages but somehow when I re-opened my project I get this. Has anyone had the same issue? Thanks in advance.

Failed to compile.

./src/lib/commerce.js
Module not found: Can't resolve '@chec/commerce.js' in '/Users/username/Desktop/e_commerce/src/lib'

Does anyone have a working AddressForm.jsx and Checkout.jsx form that conform to recent API object naming conventions?

I've completed 2/3rds of the project. I can log the token generated in Checkout.jsx and log it in the AddressForm.jsx. But when adding shippingSubdivision and setShippingOption I get HTTP 500 errors.

Any help would be appreciated! I've commented out components that were very unstable.

This is the Address Form: and Checkout is below:

import React, { useState, useEffect } from 'react';
import { InputLabel, Select, MenuItem, Button, Grid, Typography } from '@material-ui/core';
import { useForm, FormProvider } from 'react-hook-form';
import { Link } from 'react-router-dom';

import { commerce } from '../../lib/commerce';
import FormInput from './CustomTextField';

const AddressForm = ({ checkoutToken }) => {
const [shippingCountries, setShippingCountries] = useState([]);
const [shippingCountry, setShippingCountry] = useState('');
const [shippingSubdivisions, setShippingSubdivisions] = useState([]);
const [shippingSubdivision, setShippingSubdivision] = useState('');
const [shippingOptions, setShippingOptions] = useState([]);
const [shippingOption, setShippingOption] = useState('');
const methods = useForm();

const fetchShippingCountries = async (checkoutTokenId) => {
const { countries } = await commerce.services.localeListShippingCountries(checkoutTokenId);

console.log(countries);
setShippingCountries(countries);
setShippingCountry(Object.keys(countries)[0]);

};

const fetchSubdivisions = async (countryCode) => {
const { subdivisions } = await commerce.services.localeListSubdivisions(countryCode);

setShippingSubdivisions(subdivisions);
setShippingSubdivision(Object.keys(subdivisions)[0]);

};

// const fetchShippingOptions = async (checkoutTokenId, country, stateProvince = null) => {
// const options = await commerce.checkout.getShippingOptions(checkoutTokenId, { country, region: stateProvince });

// setShippingOptions(options);
// setShippingOption(options[0].id);
// };

useEffect(() => {
fetchShippingCountries(checkoutToken.id);

}, []);

useEffect(() => {
if (shippingCountry) fetchSubdivisions(shippingCountry);
}, [shippingCountry]);

// useEffect(() => {
// if (shippingSubdivision) fetchShippingOptions(checkoutToken.id, shippingCountry, shippingSubdivision);
// }, [shippingSubdivision]);

return (
    <>
        <Typography variant="h6" gutterBottom>Shipping Address</Typography>
        <FormProvider {...methods}>
            <form>
                <Grid container spacing={3}>
                <FormInput required name="firstName" label="First name" />
                <FormInput required name="lastName" label="Last name" />
                <FormInput required name="address1" label="Address line 1" />
                <FormInput required name="email" label="Email" />
                <FormInput required name="city" label="City" />
                <FormInput required name="zip" label="Zip / Postal code" />
                <Grid item xs={12} sm={6}>

                   <InputLabel>Shipping Country</InputLabel>
                  <Select value={shippingCountry} fullWidth onChange={(e) => setShippingCountry(e.target.value)}>
                  {Object.entries(shippingCountries).map(([code, name]) => ({ id: code, label: name })).map((item) => (
                  <MenuItem key={item.id} value={item.id}>
                  {item.label}
                  </MenuItem>
                   ))}
                  </Select>
                  </Grid>

                <Grid item xs={12} sm={6}>
                <InputLabel>Shipping Subdivision</InputLabel>
                <Select value={shippingSubdivision} fullWidth onChange={(e) => setShippingSubdivision(e.target.value)}>
                    {Object.entries(shippingSubdivisions).map(([code, name]) => ({ id: code, label: name })).map((item) => (
                    <MenuItem key={item.id} value={item.id}>
                        {item.label}
                    </MenuItem>
                    ))}
                </Select>
                </Grid>

                
        {/* <Grid item xs={12} sm={6}>
          <InputLabel>Shipping Options</InputLabel>
          <Select value={shippingOption} fullWidth onChange={(e) => setShippingOption(e.target.value)}>
            {shippingOptions.map((sO) => ({ id: sO.id, label: `${sO.description} - (${sO.price.formatted_with_symbol})` })).map((item) => (
              <MenuItem key={item.id} value={item.id}>
                {item.label}
              </MenuItem>
            ))}
          </Select>
        </Grid> */}
      </Grid>
      <br />
      {/* <div style={{ display: 'flex', justifyContent: 'space-between' }}>
        <Button component={Link} variant="outlined" to="/cart">Back to Cart</Button>
        <Button type="submit" variant="contained" color="primary">Next</Button>
      </div> */}
    </form>
  </FormProvider>
</>

);
};

export default AddressForm;

Checkout

import React, { useState, useEffect } from 'react'
import { Paper, Stepper, Step, StepLabel, Typography, CircularProgress, Divider, Button } from '@material-ui/core';

import { commerce } from '../../../lib/commerce';
import useStyles from './styles';
import AddressForm from '../AddressForm';
import PaymentForm from '../PaymentForm';

const steps = ['Shipping address', 'Payment details'];

const Checkout = ({ cart }) => {
const [activeStep, setActiveStep] = useState(0);
const [checkoutToken, setCheckoutToken] = useState(null);
const classes = useStyles();

useEffect(() => {
    const generateToken = async () => {
        try {
            const token = await commerce.checkout.generateToken(cart.id, {type: 'cart'});

            console.log(token);

            setCheckoutToken(token);
        } catch (error) {
            
        }
    }

    generateToken();
}, [cart]);

const Confirmation = () => (
    <div>
        Confirmation
    </div>
);

const Form = () => activeStep === 0
    ? <AddressForm checkoutToken={checkoutToken}/>
    : <PaymentForm />

return (
    <>

  <div className={classes.toolbar} />
  <main className={classes.layout}>
    <Paper className={classes.paper}>
      <Typography variant="h4" align="center">Checkout</Typography>
      <Stepper activeStep={activeStep} className={classes.stepper}>
        {steps.map((label) => (
          <Step key={label}>
            <StepLabel>{label}</StepLabel>
          </Step>
        ))}
      </Stepper>
      {activeStep === steps.length ? <Confirmation /> : checkoutToken && <Form />}
    </Paper>
  </main>
    </>
)

}

export default Checkout

How to fix CORS issue ?

Hi,
I think I am having a CORS like issue - Content Security Policy, I get the transaction completed successfully message near the end but the transaction is not going ahead because the API call was blocked.

here are some of the errors:

Content Security Policy: The page’s settings blocked the loading of a resource at eval (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at inline (“script-src”). common.js:2:319 Content Security Policy: The page’s settings blocked the loading of a resource at inline (“script-src”). pagewrap.bundle.js:1:1151 Content Security Policy: The page’s settings blocked the loading of a resource at inline (“script-src”). onloadwff.js:71:790746 Content Security Policy: The page’s settings blocked the loading of a resource at eval (“script-src”). Uncaught DOMException: Permission denied to access property "dispatchEvent" on cross-origin object inject.js:65 Uncaught DOMException: Permission denied to access property "dispatchEvent" on cross-origin object inject.js:65 Uncaught DOMException: Permission denied to access property "dispatchEvent" on cross-origin object inject.js:65

I thought it was a CORS issue - retrieving from another domain, but its Content Security Policy thing.

There was an answer on stackover flow but I couldn't get it to work :
https://stackoverflow.com/questions/59592929/content-security-policy-in-react-app-didnt-block-online-script

How do you fix Content Security Policy on this React project ?

ERROR in ./src/components/CheckoutForm/Checkout/Checkout.jsx

Two similar errors with exporting useHistory any idea?

ERROR in ./src/components/CheckoutForm/Checkout/Checkout.jsx 30:18-28

export 'useHistory' (imported as 'useHistory') was not found in 'react-router-dom' (possible exports: BrowserRouter, HashRouter, Link, MemoryRouter, NavLink, Navigate, Outlet, Route, Router, Routes, UNSAFE_LocationContext, UNSAFE_NavigationContext, UNSAFE_RouteContext, createRoutesFromChildren, createSearchParams, generatePath, matchPath, matchRoutes, renderMatches, resolvePath, unstable_HistoryRouter, useHref, useInRouterContext, useLinkClickHandler, useLocation, useMatch, useNavigate, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRoutes, useSearchParams)

ERROR in ./src/components/CheckoutForm/Checkout/Checkout.jsx 227:21-31

export 'useHistory' (imported as 'useHistory') was not found in 'react-router-dom' (possible exports: BrowserRouter, HashRouter, Link, MemoryRouter, NavLink, Navigate, Outlet, Route, Router, Routes, UNSAFE_LocationContext, UNSAFE_NavigationContext, UNSAFE_RouteContext, createRoutesFromChildren, createSearchParams, generatePath, matchPath, matchRoutes, renderMatches, resolvePath, unstable_HistoryRouter, useHref, useInRouterContext, useLinkClickHandler, useLocation, useMatch, useNavigate, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRoutes, useSearchParams)

customer payload object sent to Stripe is empty. shippingData not being set in PaymentForm.jsx 422 error

I'm about 3/4 of the way through the video and really enjoying it so far. I'm struggling with the ShippingData part. For some reason it doesn't look like the FormInput fields are being set in shippingData request payload to api.chec - As you can see its an empty object below

{,…} customer: {} fulfillment: {shipping_method: "ship_p6dP5gbmYon7kA"} line_items: [{id: "item_7RyWOwmK5nEa2V", product_id: "prod_Kvg9l61n0d51bB", name: "Robin Hood",…},…] payment: {gateway: "stripe", stripe: {payment_method_id: "pm_1KhaFELTXNlEjoivg8TNLkUu"}} shipping: {name: "Primary", county_state: "IA", country: "US"}

{"status_code":422,"error":{"message":"The given data was invalid.","type":"unprocessable_entity","errors":{"customer.email":["The Email field is required when customer.id is not present."],"shipping.street":["The Shipping street address field is required when customer.id is not present."],"shipping.town_city":["The Shipping town\/city field is required when customer.id is not present."]}},

Only the fields that have a set like SetShippingCountries are being passed to the ShippingData.. The other values that come from the onSubmit are not being populated - The fields shown below do not pass into customer or shipping.

<FormInput name='firstName' label='First name' /> <FormInput name='lastName' label='Last name' /> <FormInput name='address1' label='Address line 1' /> <FormInput name='email' label='Email' /> <FormInput name='city' label='City' /> <FormInput name='zip' label='ZIP / Postal Code' />

Here's my AddressForm.jsx
`import React, { useState, useEffect } from 'react';
import {
InputLabel,
Select,
MenuItem,
Button,
Grid,
Typography,
} from '@material-ui/core';

import { useForm, FormProvider } from 'react-hook-form';
import { Link } from 'react-router-dom';

import { commerce } from '../../lib/commerce';
import FormInput from './CustomTextField';

const AddressForm = ({ checkoutToken, test }) => {
const [shippingCountries, setShippingCountries] = useState([]);
const [shippingCountry, setShippingCountry] = useState('');
const [shippingSubdivisions, setShippingSubdivisions] = useState([]);
const [shippingSubdivision, setShippingSubdivision] = useState('');
const [shippingOptions, setShippingOptions] = useState([]);
const [shippingOption, setShippingOption] = useState('');
const methods = useForm();

const countries = Object.entries(shippingCountries).map(([code, name]) => ({
id: code,
label: name,
}));

const subdivisions = Object.entries(shippingSubdivisions).map(
([code, name]) => ({
id: code,
label: name,
})
);

const options = shippingOptions.map((so) => ({
id: so.id,
label: ${so.description} - (${so.price.formatted_with_symbol}),
}));

const fetchShippingCountries = async (checkoutTokenId) => {
const { countries } = await commerce.services.localeListShippingCountries(
checkoutTokenId
);

// console.log(countries);
setShippingCountries(countries);
setShippingCountry(Object.keys(countries)[0]);

};

const fetchSubdivisions = async (countryCode) => {
const { subdivisions } = await commerce.services.localeListSubdivisions(
countryCode
);

setShippingSubdivisions(subdivisions);
setShippingSubdivision(Object.keys(subdivisions)[0]);

};

const fetchShippingOptions = async (
checkoutTokenId,
country,
// region = null
stateProvince
) => {
const options = await commerce.checkout.getShippingOptions(
checkoutTokenId,
{ country, stateProvince }
);

setShippingOptions(options);
setShippingOption(options[0].id);

};

useEffect(() => {
fetchShippingCountries(checkoutToken.id);
}, []);

useEffect(() => {
if (shippingCountry) fetchSubdivisions(shippingCountry);
}, [shippingCountry]);

useEffect(() => {
if (shippingSubdivision)
fetchShippingOptions(
checkoutToken.id,
shippingCountry,
shippingSubdivision
);
}, [shippingSubdivision]);

return (
<>

Shipping Address

<FormProvider {...methods}>
<form
onSubmit={methods.handleSubmit((data) =>
test({
...data,
shippingCountry,
shippingSubdivision,
shippingOption,
})
)}
>








Shipping Country
<Select
value={shippingCountry}
fullwidth='true'
onChange={(e) => setShippingCountry(e.target.value)}
>
{countries.map((country) => (

{country.label}

))}



Shipping Subdivision
<Select
value={shippingSubdivision}
fullwidth='true'
onChange={(e) => setShippingSubdivision(e.target.value)}
>
{subdivisions.map((subdivision) => (

{subdivision.label}

))}



Shipping Options
<Select
value={shippingOption}
fullwidth='true'
onChange={(e) => setShippingOption(e.target.value)}
>
{options.map((option) => (

{option.label}

))}





<div style={{ display: 'flex', justifyContent: 'space-between' }}>

Back to Cart


Next




</>
);
};

export default AddressForm;
`
Here's my PaymentForm.jsx

`import React from 'react';
import { Typography, Button, Divider } from '@material-ui/core';
import {
Elements,
CardElement,
ElementsConsumer,
} from '@stripe/react-stripe-js';
import { loadStripe } from '@stripe/stripe-js';

import Review from './Review';

const stripePromise = loadStripe(process.env.REACT_APP_STRIPE_PUBLIC_KEY);

const PaymentForm = ({
checkoutToken,
backStep,
nextStep,
shippingData,
onCaptureCheckout,
}) => {
const handleSubmit = async (event, elements, stripe) => {
event.preventDefault();

if (!stripe || !elements) return;

const cardElement = elements.getElement(CardElement);

const { error, paymentMethod } = await stripe.createPaymentMethod({
  type: 'card',
  card: cardElement,
});

if (error) {
  console.log('[error]', error);
} else {
  const orderData = {
    line_items: checkoutToken.live.line_items,
    customer: {
      firstname: shippingData.firstName,
      lastname: shippingData.lastName,
      email: shippingData.email,
      // firstname: 'John',
      // lastname: 'Smith',
      // email: '[email protected]',
    },
    shipping: {
      name: 'Primary',
      street: shippingData.address1,
      town_city: shippingData.city,
      county_state: shippingData.shippingSubdivision,
      postal_zip_code: shippingData.zip,
      country: shippingData.shippingCountry,
    },
    fulfillment: { shipping_method: shippingData.shippingOption },
    payment: {
      gateway: 'stripe',
      stripe: {
        payment_method_id: paymentMethod.id,
      },
    },
  };
  onCaptureCheckout(checkoutToken.id, orderData);

  nextStep();
}

};

return (
<>


<Typography variant='h6' gutterBottom style={{ margin: '20px 0' }}>
Payment method



{({ elements, stripe }) => (
<form onSubmit={(e) => handleSubmit(e, elements, stripe)}>




<div style={{ display: 'flex', justifyContent: 'space-between' }}>

Back


Pay {checkoutToken.live.subtotal.formatted_with_symbol}



)}


</>
);
};

export default PaymentForm;
`

Here's my app.js

`import React, { useState, useEffect } from 'react';
import { commerce } from './lib/commerce';
import { Products, Navbar, Cart, Checkout, PageNotFound } from './components';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';

const App = () => {
const [products, setProducts] = useState([]);
const [cart, setCart] = useState({});
const [order, setOrder] = useState({});
const [errorMessage, setErrorMessage] = useState('');

const fetchProducts = async () => {
const { data } = await commerce.products.list();
setProducts(data);
};

const fetchCart = async () => {
setCart(await commerce.cart.retrieve());
};

const handleAddToCart = async (productId, quantity) => {
const item = await commerce.cart.add(productId, quantity);

setCart(item.cart);

};

const handleUpdateCartQty = async (productId, quantity) => {
const { cart } = await commerce.cart.update(productId, { quantity });

setCart(cart);

};

const handleRemoveFromCart = async (productId) => {
const { cart } = await commerce.cart.remove(productId);

setCart(cart);

};

const handleEmptyCart = async () => {
const { cart } = await commerce.cart.empty();

setCart(cart);

};

const refreshCart = async () => {
const newCart = await commerce.cart.refresh();

setCart(newCart);

};

const handleCaptureCheckout = async (checkoutTokenId, newOrder) => {
try {
console.log(HandleCaptureCheckout Function entered);
const incomingOrder = await commerce.checkout.capture(
checkoutTokenId,
newOrder
);
setOrder(incomingOrder);
console.log(This is neworder ${newOrder});
console.log(This is incomingOrder ${incomingOrder});

  refreshCart();
} catch (error) {
  setErrorMessage(error.data.error.message);
}

};

useEffect(() => {
fetchProducts();
fetchCart();
}, []);

//console.log(products);
// console.log(cart);

return (

















);
};

export default App;
`

Here's my App.js

import React, { useState, useEffect } from 'react';
import {
InputLabel,
Select,
MenuItem,
Button,
Grid,
Typography,
} from '@material-ui/core';

import { useForm, FormProvider } from 'react-hook-form';
import { Link } from 'react-router-dom';

import { commerce } from '../../lib/commerce';
import FormInput from './CustomTextField';

const AddressForm = ({ checkoutToken, test }) => {
const [shippingCountries, setShippingCountries] = useState([]);
const [shippingCountry, setShippingCountry] = useState('');
const [shippingSubdivisions, setShippingSubdivisions] = useState([]);
const [shippingSubdivision, setShippingSubdivision] = useState('');
const [shippingOptions, setShippingOptions] = useState([]);
const [shippingOption, setShippingOption] = useState('');
const methods = useForm();

const countries = Object.entries(shippingCountries).map(([code, name]) => ({
id: code,
label: name,
}));

const subdivisions = Object.entries(shippingSubdivisions).map(
([code, name]) => ({
id: code,
label: name,
})
);

const options = shippingOptions.map((so) => ({
id: so.id,
label: ${so.description} - (${so.price.formatted_with_symbol}),
}));

const fetchShippingCountries = async (checkoutTokenId) => {
const { countries } = await commerce.services.localeListShippingCountries(
checkoutTokenId
);

// console.log(countries);
setShippingCountries(countries);
setShippingCountry(Object.keys(countries)[0]);

};

const fetchSubdivisions = async (countryCode) => {
const { subdivisions } = await commerce.services.localeListSubdivisions(
countryCode
);

setShippingSubdivisions(subdivisions);
setShippingSubdivision(Object.keys(subdivisions)[0]);

};

const fetchShippingOptions = async (
checkoutTokenId,
country,
// region = null
stateProvince
) => {
const options = await commerce.checkout.getShippingOptions(
checkoutTokenId,
{ country, stateProvince }
);

setShippingOptions(options);
setShippingOption(options[0].id);

};

useEffect(() => {
fetchShippingCountries(checkoutToken.id);
}, []);

useEffect(() => {
if (shippingCountry) fetchSubdivisions(shippingCountry);
}, [shippingCountry]);

useEffect(() => {
if (shippingSubdivision)
fetchShippingOptions(
checkoutToken.id,
shippingCountry,
shippingSubdivision
);
}, [shippingSubdivision]);

return (
<>

Shipping Address

<FormProvider {...methods}>
<form
onSubmit={methods.handleSubmit((data) =>
test({
...data,
shippingCountry,
shippingSubdivision,
shippingOption,
})
)}
>








Shipping Country
<Select
value={shippingCountry}
fullwidth='true'
onChange={(e) => setShippingCountry(e.target.value)}
>
{countries.map((country) => (

{country.label}

))}



Shipping Subdivision
<Select
value={shippingSubdivision}
fullwidth='true'
onChange={(e) => setShippingSubdivision(e.target.value)}
>
{subdivisions.map((subdivision) => (

{subdivision.label}

))}



Shipping Options
<Select
value={shippingOption}
fullwidth='true'
onChange={(e) => setShippingOption(e.target.value)}
>
{options.map((option) => (

{option.label}

))}





<div style={{ display: 'flex', justifyContent: 'space-between' }}>

Back to Cart


Next




</>
);
};

export default AddressForm;

Help!!!!

i am getting an error saying id is undefined when i try to get shippingOptions[0].id??

please help i get this error when i go for payment option

×
←→1 of 6 errors on the page
TypeError: props.render is not a function
Controller
C:/Users/parvi/Desktop/src/controller.tsx:4
1 | import { ControllerProps, FieldPath, FieldValues } from './types';
2 | import { useController } from './useController';
3 |

4 | const Controller = <
5 | TFieldValues extends FieldValues = FieldValues,
6 | TName extends FieldPath = FieldPath,
7 | >(
View compiled
▶ 18 stack frames were collapsed.
generateToken
C:/Users/parvi/Desktop/test/src/components/CheckoutForm/Checkout/Checkout.jsx:28
25 | try {
26 | const token = await commerce.checkout.generateToken(cart.id, { type: 'cart' });
27 |
28 | setCheckoutToken(token);
| ^ 29 | } catch {
30 | if (activeStep !== steps.length) history.push('/');
31 | }
View compiled

TypeError: Cannot read property 'length' of undefined

Hi, I am in the Cart Layout part in your tutorial.

While trying to access the line_items property of the cart, it seems it is null or undefined.

How do I fix this?

Error:

image

My Code:
image

If you find the solution, please let me know asap.

Thanks!

TypeError: onAddToCart

This is video is awesome. I am experiencing a problem when adding items to the cart. This type Error appears on the web page
TypeError: onAddToCart is not a function can anyone help with this?

Below I have included the App.js, Products.js and Product.js code

App.js:

import React, { useState, useEffect } from 'react';
import { commerce } from './lib/commerce';
import { Products, Navbar } from './components';

const App = () => {
const [products, setProducts] = useState([]);
const [cart, setCart] = useState({});

const fetchProducts = async () => {
    const { data } = await commerce.products.list();

    setProducts(data);
}

const fetchCart = async () => {
    
        setCart(await commerce.cart.retrieve())
    }

const handleAddToCart = async (productId, quantity) => {
    const item = await commerce.cart.add(productId, quantity);

    setCart(item.cart);
}

useEffect(() =>{
    fetchProducts();
    fetchCart();
}, []);

console.log(cart);

return (
    <div>
        <Navbar />
        <Products products={products} onAddtoCart={ handleAddToCart } />
    </div>
)

}

export default App

Products.js

import React from 'react';

import { Grid } from '@material-ui/core';

import Product from './Product/Product';
import useStyles from './styles';

const Products = ({ products, onAddToCart }) => {
const classes = useStyles();

return (
    <main className={classes.content}>
        <div className={classes.toolbar} />
<Grid container justifyContent="center" spacing={4}>
    {products.map((product) => (
        <Grid item key={product.id} xs={12} sm={6} md={4} lg={3}>
                <Product product={product} onAddtoCart={onAddToCart} />
            </Grid>
    ))}
</Grid>
);

}

export default Products

Product.js

import React from 'react';
import { Card, CardMedia, CardContent, CardActions, Typography, IconButton } from '@material-ui/core';
import { AddShoppingCart } from '@material-ui/icons';
import useStyles from './styles';

const Product = ({ product, onAddToCart }) => {
const classes = useStyles();

return (
    <Card className={classes.root}>
        <CardMedia className={classes.media} image={product.media.source} title={Product.name} />
        <CardContent>
            <div className={classes.CardContent}>
                <Typography variant="h5" gutterBottom>
                    {product.name}
                </Typography>
                <Typography variant="h5" >
                    {product.price.formatted_with_symbol}
                </Typography>
            </div>
            <Typography dangerouslySetInnerHTML={{ __html: product.description }} variant="body2" color="textSecondary" />
                    
        </CardContent>
        <CardActions disableSpacing className={classes.cardActions}>
            <IconButton aria-label="Add to Cart" onClick={() => onAddToCart(product.id, 1)}>
                <AddShoppingCart />
            </IconButton>
        </CardActions>

    </Card>
)

}

export default Product

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.