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
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
});
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))
};
Related
So I am making a request to an API endpoint. When I print JSONBody which is the variable data passed to POSTRequest(), I get the JSON I created printed to the log, however when I then try and JSON.Stringify() it, I get returned an empty object?
Was just wondering what I am doing wrong and how to fix it :)
getFileData()
const getFileData = () => {
var data = {}
// DO SOME STUFF HERE TO data
POSTRequest(data);
}
POSTRequest()
const POSTRequest = async (JSONBody) => {
console.log(JSONBody)
console.log(JSON.stringify(JSONBody))
try {
const response = await fetch(API_ENDPOINT, {
method: 'POST',
body: JSON.stringify(JSONBody),
headers: { 'Content-Type': 'application/json' }
});
response.json()
.then(function (res) {
Promise.resolve(res)
.then(function (finalData) {
console.log(finalData);
props.setData(finalData);
});
});
} catch (error) {
console.log(error);
}
}
You're not waiting for the response from the fetch call correctly, try this:
const POSTRequest = async (JSONBody) => {
console.log(JSONBody)
console.log(JSON.stringify(JSONBody))
await fetch(API_ENDPOINT, {
method: 'POST',
body: JSON.stringify(JSONBody),
headers: { 'Content-Type': 'application/json' }
}).then((response) => {
console.log(response);
props.setData(response);
}).catch((error) => {
console.log('POSTRequest error: ' + error)
})
});
When I open my local host, I am getting the following error
Uncaught (in promise) TypeError: Failed to execute 'fetch' on 'Window': Failed to parse URL from //at getData ((index):60)
Which is pointing to these lines of code
const response = await fetch(url, {
&
getData(`/${url}`)
I'm not sure why I am getting this error when I load the page, as should I only get something like this when I search for something?
This is the larger block of code I am referring to:
document.getElementById('search').addEventListener('submit', function(e) { e.preventDefault(); getData(); })
const form = document.getElementById('Submit')
var formResult = new FormData(form);
const url = '/' + encodeURIComponent(formResult.get("search"));
async function getData(url = '', data = {}) {
const response = await fetch(url, {
method: 'GET',
mode: 'cors',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
},
});
return response.json();
}
getData(`/${url}`)
.then(data => {
console.log(data);
})
Any insight would be appreciated.
Edit based on comments:
Front end:
const form = document.getElementById('Submit')
var formResult = new FormData(form);
const url = '/?url=' + encodeURIComponent(formResult.get("search"));
async function getData(url = '', data = {}) {
const response = await fetch(url) {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
.then(response =>{
console.log(response)
})
.catch(err=>{
console.error(err)
})
Portion of my express Server:
const url = req.body
let urlDecoded = decodeURIComponent(url.url)
console.log(url, urlDecoded)
app.use(express.static("Public"));
app.post('/:url', async function (req, res) {
console.log(req.query.url);
try {
await whoisanalyzer.init();
const site = await whoisanalyzer.open(decodeURIComponent(req.query.url));
const data = await site.analyze();
return res.status(200).json(data);
} catch (ex) {
console.log(ex);
return res.status(500).json({ message : "Oops." });
}});
I think the problem is in the getData() function because of the parameter of it getData(url=' ')
The getData() function replace url with the parameter not with the variable so the fetch url is gonna be
Fetch(" ", { ....})
You have to define the url or the parameter with anther name
You also call the function inside the same function in
getData(`/${url}`)
.then(data => {
console.log(data);
})
That is wrong because the function will never end
You can do it directly like that
document.getElementById('search').addEventListener('submit', async function(e) {
e.preventDefault();
const form = document.getElementById('Submit')
var formResult = new FormData(form);
const url = '/' + encodeURIComponent(formResult.get("search"));
const response = await fetch(url)
.then(response =>{
console.log(response)
})
.catch(err=>{
cosnole.error(err)
})
if you want to take a url and send it to the back end and your front end code is like this
<form action="POST">
<input type="text" name="url">
<input type="submit" value="press">
</form>
so your the code in your js file is gonna be like this below :-
const form = document.querySelector('form')
form.addEventListener('submit', async(e) => {
e.preventDefault()
let urlIN = form.url.value
let url = encodeURIComponent(urlIN)
console.log(url)
const data = await fetch('/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: url
})
}).then(data => {
console.log(data)
console.log('get')
})
.catch(err => {
console.error(err)
})
})
and i tested it and it's working , i could send the url of this page and decoded it and i printed it in my console like that
my back end code
const url = req.body
let urlDecoded = decodeURIComponent(url.url)
console.log(url, urlDecoded)
and the result is
{
url: 'https%3A%2F%2Fstackoverflow.com%2Fquestions%2F65757144%2Ferror-when-page-loads-but-before-anything-is-executed%2F65760895%3Fnoredirect%3D1%23comment116273379_65760895'
}
Error when page loads, but before anything is executed
I've seen several posts about this, so I apologize if it's a direct duplicate. The examples I've seen have the RN components built with classes. I'm using functions, and I'm new, so it's all very confusing.
const getFlights = async () => {
const token = await getAsyncData("token");
instance({
method: "get",
url: "/api/flights/",
headers: {
Authorization: `Token ${token}`,
},
})
.then(function (response) {
// console.log(response.data.results); // shows an array of JSON objects
return response.data.results; // I've also tried response.data.results.json()
})```
I just want the response returned as a variable that I can use to populate a FlatList component in RN.
const FlightListScreen = () => {
const [list, setList] = useState([]);
const flights = getFlights(); // currently returns as a promise object
Thank you for your help.
I think you have to store the response object directly to the json method. And then with that response you can store it to the variable
.then(response => { return response.json() })
.then(response => {
this.setState({
list: response
})
you are sending token without a bearer. Concrete your token with bearer like this
headers: {
Authorization: "Bearer " + token,
},
and another thing is your response class are not right this should be like this
.then((response) => response.json())
.then((responseJson) => {
API will Resopne here....
}
this is a complete example to call API with Token
fetch("/api/flights/", {
method: "GET",
headers: {
Authorization: "Bearer " + token,
},
})
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson);
setState(responseJson.VAlue);
})
.catch((error) => {
alert(error);
});
Server
const express = require("express");
const app = express();
app.listen(4000, () => console.log("listening at 4000"));
app.use(express.static("public"));
app.use(express.json({limit: "1mb"}));
//POST method route
app.post("/clientApi", (req, res) => {
// res.send("POST request to the homepage")
console.log(req.body);
});
Client
function checkData() {
let summoner = playerName.value;
let fetchData = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(summoner),
}
fetch("/clientApi", fetchData)
.then(response => response.json())
.then(data => {
console.log("Success: ", data);
});
}
Everything worked fine until I tried calling for Express.json but I don't see any syntax error.
The client side could send data to the server.
But it was too much data so I used "req.body" to try and get exactly what I wanted, but on the terminal its undefined. So that's when I decided to try using express.json which is where the error came up.
Error Message
Uncaught (in promise) SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
You forgot the {} after app.listen(4000, () => {console.log("listening at 4000")}); that should fix it
Actually you forgot to make proper JSON formate at client site:
function checkData() {
let summoner = playerName.value;
let sendData = {};
sendData.summoner = summoner;
let fetchData = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(sendData),
}
fetch("/clientApi", fetchData)
.then(response => response.json())
.then(data => {
console.log("Success: ", data);
});
}
NOTE: Data you pass inside JSON.stringify() should a proper JSON Object. So that it can parse on the other side.
Try sending an object rather than just a string stringified such as
<script>
const playerName = {
value: "foobar"
};
function checkData() {
const summoner = { ...playerName };
const fetchData = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(summoner),
}
fetch("/clientApi", fetchData)
.then(response => response.json())
.then(data => {
console.log("Success: ", data);
});
}
checkData();
</script>
Express won't be able to decode it otherwise.
Shouldn't fetch("/clientApi", fetchData) include http://localhost:4000/clientApi?
I'm trying to make a POST request with a GraphQL query, but it's returning the error Must provide query string, even though my request works in PostMan.
Here is how I have it running in PostMan:
And here is the code I'm running in my application:
const url = `http://localhost:3000/graphql`;
return fetch(url, {
method: 'POST',
Accept: 'api_version=2',
'Content-Type': 'application/graphql',
body: `
{
users(name: "Thomas") {
firstName
lastName
}
}
`
})
.then(response => response.json())
.then(data => {
console.log('Here is the data: ', data);
...
});
Any ideas what I'm doing wrong? Is it possible to make it so that the body attribute I'm passing in with the fetch request is formatted as Text like I've specified in the PostMan request's body?
The body is expected to have a query property, containing the query string. Another variable property can be passed as well, to submit GraphQL variables for the query as well.
This should work in your case:
const url = `http://localhost:3000/graphql`;
const query = `
{
users(name: "Thomas") {
firstName
lastName
}
}
`
return fetch(url, {
method: 'POST',
Header: {
'Content-Type': 'application/graphql'
}
body: query
})
.then(response => response.json())
.then(data => {
console.log('Here is the data: ', data);
...
});
This is how to submit GraphQL variables:
const query = `
query movies($first: Int!) {
allMovies(first: $first) {
title
}
}
`
const variables = {
first: 3
}
return fetch('https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr', {
method: 'post',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({query, variables})
})
.then(response => response.json())
.then(data => {
return data
})
.catch((e) => {
console.log(e)
})
I created a complete example on GitHub.