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