skip to Main Content

I have this code that sends me back an url and an error. I’m trying to access the url so I can navigate to it with router.

With this code:

const redirectToStripe = async () => {
  const response = await fetch(
    "http://localhost:5000/create-checkout-session",
    {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },
      body: JSON.stringify(cartItems.value),
    }
  )
    .then((response) => response.json())
    .then((response) =>
      console.log("stringied response", JSON.stringify(response))
    );

  const { url } = await response.json();
  console.log("url=", url);  <--------------Doesn't execute, no console.log() readout

  // window.location.href = url;
  // router.go(url)  <------- NEED TO FIX THIS AND UNCOMMENT;
};

I get this error:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘json’)
at redirectToStripe

and this console.log() readout:

stringied response {"url":"https://checkout.stripe.com/c/pay/cs_test_a1X3r92YtZfM9H"}

That is the url I’m trying to navigate to, but I don’t know how to access it in this stringified form. How do I grab the value of "url" so I can put it in the function:

router.go(url)

The later "url" console.log() never executes because of the json error (pretty sure), but I’m guessing it’s the same url as the stringified one above?


I also don’t know why I’m getting that error or if it’s even consequential and needs to be fixed because I’m already getting the url I need. Does the error have something to do with the "Content-Type" header? Did I pick the right one? Is it something else I’m doing wrong?


Also, this is what the backend endpoint looks like if it adds context or anything.

app.post("/create-checkout-session", async (req, res) => {
  // Make an array of just our Stripe Price ID and quantities
  const lineItems = req.body.map((item) => {
    console.log("lineItems= ", item.item.priceId, item.item.quantity);
    return {
      price: item.item.priceId,
      quantity: item.item.quantity,
    };
  });

  const session = await stripe.checkout.sessions.create({
    mode: "payment",
    line_items: lineItems,
    success_url: `http://localhost:8080/success?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `http://localhost:8080/`,
  });
  return res.send({ url: session.url });
});

EDITS

@pope_maverick

This code:

const redirectToStripe = () => {
  const response = fetch("http://localhost:5000/create-checkout-session", {
    method: "POST",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
    },
    body: JSON.stringify(cartItems.value),
  }).then((response) => response.json());
  const {url} = response.json();
  // const { url } = await response.json();
  console.log("url=", url);

gets me the error:

Uncaught TypeError: response.json is not a function

2

Answers


  1. You face this issue because the API returns a string not an object so you are suppsed to use Response.text() over Response.json(), have a look the MDN Response.text()

    Try below:

    const redirectToStripe = async () => {
          const response = await fetch(
            "http://localhost:5000/create-checkout-session",
            {
              method: "POST",
              headers: {
                Accept: "application/json",
                "Content-Type": "application/json",
              },
              body: JSON.stringify(cartItems.value),
            }
          )
            .then(response => response.text())
            .then((url) => {
            const { url } = url;
            console.log("url=", url); 
            router.go(url)
       })
       .catch(err => console.log(err))
         
        };
    
    Login or Signup to reply.
  2. You forgot to return the response in your last .then callback. So your const response is actually void.

    const response = await fetch(
        "http://localhost:5000/create-checkout-session",
        // [...]
      )
        .then((response) => response.json())
        .then((response) => {
          console.log("stringied response", JSON.stringify(response))
          // ❗️ Return `response` here, or the Promise will return the returned value of `console.log` which is `void`!
          return response
        });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search