Home > OS >  How to access property of stringified JSON?
How to access property of stringified JSON?

Time:01-31

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

CodePudding user response:

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
    });

CodePudding user response:

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))
     
    };

CodePudding user response:

Adding an explanation: since the resolved value is already response.json() you just need to access the url property of that value.

const redirectToStripe = async () => {
  const { url } = 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())

  router.go(url)  <------- NEED TO FIX THIS AND UNCOMMENT;
};
  • Related