Error when page loads, but before anything is executed - javascript

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

Related

How to access property of stringified JSON?

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

axios vs fetch throwing error on file upload

I am using fetch instead of axios in my react project
my this method working fine with the axios to upload an image on the server
Upload image function
<Upload customRequest={dummyRequest} className="upload-btn-container" onChange={onChange}>
<Button className="btn custom-upload-btn">Upload Image</Button>
</Upload>
const uploadPicture = async (data) =>{
const value = await getUploadPicture(data)
if(value.value.data.status){
await addImage(value.value.data.data)
}
}
const onChange = async (info) => {
for (let i = 0; i < info.fileList.length; i++) {
const data = new FormData();
data.append('file', info.fileList[i]);
data.append('filename', info.fileList[i].name);
setImgName(info.fileList[i].name)
let value = await uploadPicture(data);
}
};
return axios({
method: 'post',
url: `${NewHostName}/upload`,
headers: {
'Content-Type': 'application/json',
'Authorization': localStorage.getItem('authToken')
},
data:data
})
.then(response => {
return response
}).catch(err => {
console.log("err", err)
})
whereas when I do same with the fetch it throws me error on the backend "Cannot read property of split of undefined"
return fetch(`${NewHostName}/upload`, {
method: "post",
headers: {
"Content-Type": "application/json",
Authorization: localStorage.getItem('authToken'),
},
body: JSON.stringify(data),
// body :data
})
.then((res) => {
return res.json();
})
.then((payload) => {
return payload;
})
.catch((err) => {
throw err;
})
Not sure what is the reason behind this
this is my backend upload api
const handler = async (request, reply) => {
try {
const filename = request.payload.filename
const fileExtension = filename.split('.').pop()
AWS.config.update({
accessKeyId: Config.get('/aws').accessKeyId,
secretAccessKey: Config.get('/aws').secretAccessKey,
region: Config.get('/aws').region
})
const s3 = new AWS.S3({
params: {
Bucket: Config.get('/aws').bucket
}
})
const Key = `/${shortid.generate()}.${fileExtension}`
const obj = {
Body: request.payload.file,
Key,
ACL: 'public-read'
}
s3.upload(obj, async (err, data) => {
if (err) {
return reply({ status: false, 'message': err.message, data: '' }).code(Constants.HTTP402)
} else if (data) {
return reply({ status: true, 'message': 'ok', data: data.Location }).code(Constants.HTTP200)
}
})
} catch (error) {
return reply({
status: false,
message: error.message,
data: ''
})
}
}
data is a FormData object.
In your original code you are lying when you say 'Content-Type': 'application/json'. Possibly Axios recognises that you've passed it a FormData object and ignores your attempt to override the Content-Type.
Your fetch code, on the other hand, says body: JSON.stringify(data) which tries to stringify the FormData object and ends up with "{}" which has none of your data in it.
Don't claim you are sending JSON
Don't pass your FormData object through JSON.stringify
For image upload you not use JSON.stringify(data).You can try with formData and append an image file with form data.
var formdata = new FormData();
formdata.append("image", data);
Did you check that
const filename = request.payload.filename
exists?
Is the key really payload? The following does not make any changes to your code:
.then((payload) => {
return payload;
})

Error when page loads, instead of after form submit?

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.
for clarity on backend:
app.get('/:url', async function (req, res) {
console.log(req.params.url);
try {
await whoisssubmit.init();
const site = await whoisssubmit.open(decodeURIComponent(req.params.url));
const data = await site.analyze();
return res.status(200).json(data);
} catch (ex) {
console.log(ex);
return res.status(500).json({ message : "Oops." });
}});
Actually, you are calling getData() at the end of the snippet that you provided.
// Add url
const url = 'urlToApi';
document.getElementById('search').addEventListener('submit', function(e) { e.preventDefault(); getData(url).then(response => console.log(response)); })
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();
}

Django CSRFToken middleware appends to URL and shows up after making a “PUT” request to the server. (AJAX issue)

I’m working on a Django Python/Javascript project. The PUT request is done through the client and sent back to the server. After sending the request successfully, the page makes a refresh which is causing the exposure of the csrf token middleware in the URL. I already implemented AJAX, returning false, added an event.preventDefault(), passed a cookie through the header of the fetch, used async functions, and added a try and catch syntax. And I can’t figure out why it is not affecting the resubmission. I need to stop the webpage from refreshing once the submission is done so that the csrf_token won't show appended to the URL.
Hopefully, someone can let me know what I’m not seeing here. Thanks!
// Set global variables to use in form submission
var id, upt_prodName, upt_prodPrice, upt_prodDescpt;
// Block to populate textarea that allows the user to update product info.
const editProd_view = (response) => {
let prod_id = response.id;
let edit_name = response.name;
let edit_price = response.price;
let edit_descpt = response.description;
let prod_idUpt = (document.querySelector("#prod_idUpt").innerHTML = prod_id);
let new_name = (document.querySelector(
"#editProdName"
).innerHTML = edit_name);
let new_price = (document.querySelector(
"#editProdPrice"
).innerHTML = edit_price);
let new_textarea = (document.querySelector(
"#editProdDescpt"
).innerHTML = edit_descpt);
id = prod_id;
//On submit, send product info to update the product.
const edit_prod = (document.querySelector(
"#editProd_form").onsubmit = async () => {
try {
// Get all values from textarea to update content.
upt_prodName = document.getElementById("editProdName").value;
new_prodPrice = document.getElementById("editProdPrice").value;
new_prodDescpt = document.getElementById("editProdDescpt").value;
const res = await fetch(
`/editProduct/${id}`,
{
method: "PUT",
headers: {
"Content-Type": "application/json",
"X-CSRFToken": getCookie("csrftoken"),
},
body: JSON.stringify({
name: upt_prodName,
description: upt_prodDescpt,
price: upt_prodPrice,
}),
})
.then((res) => res.json())
.then((result) => {
console.log("result ->", result);
});
} catch (err) {
console.error("err", err);
}
//Once the post has been submitted, return false to prevent reloading.
edit_prod.handleForm();
return false;
});
return false;
};
Yeah inside django for post and put, delete requires a csrf token, my solution
you can do this
<form>
<button id="onsubmit" method="{{csrf_token}}">submit</button>
</form>
$(document).on(function() {
$(document).on('click', '#onsubmit', function() {
var token = $(this).attr("method")
const res = await fetch(
`/editProduct/${id}`,
{
method: "PUT",
headers: {
"Content-Type": "application/json",
"X-CSRFToken": token,
},
body: JSON.stringify({
name: upt_prodName,
description: upt_prodDescpt,
price: upt_prodPrice,
}),
})
.then((res) => res.json())
.then((result) => {
console.log("result ->", result);
});
} catch (err) {
console.error("err", err);
}
})
})

2 API Calls in One JavaScript

presently I am attempting to make 2 different api calls one after the other within 1 java/nodejs script. It seems after my first function runs successfully, the second one errors with the following:
FetchError: request to failed, reason: socket hang up;
type: 'system',
errno: 'ECONNRESET',
code: 'ECONNRESET'
Below is a code snippet of what I have tried thus far:
const fetch = require("node-fetch");
const formData = require("form-data");
const fs = require("fs");
//const express = require("express");
var apiName = "<LOCAL SYSTEM FILE TO UPLOAD>";
var lookupName = "<LOCAL SYSTEM FILE TO UPLOAD>";
var accessToken = "Bearer <ACCESS TOKEN>";
var url = '<URL API #1>';
var url2 = '<URL API #2>;
var headers = {
'Accept': 'application/json',
'Authorization': accessToken,
};
const form = new formData();
const buffer2 = fs.readFileSync(lookupName);
const buffer = fs.readFileSync(apiName);
const uploadAPI = function uploadAPI() {
form.append("Content-Type", "application/octect-stream");
form.append('file', buffer);
fetch(url, {method: 'POST', headers: headers, body: form})
.then(data => {
console.log(data)
})
.catch(err => {
console.log(err)
});
};
const uploadLookup = function uploadLookup() {
form.append("Content-Type", "application/octect-stream");
form.append('file', buffer2);
fetch(url2, {method: 'PUT', headers: headers, body: form})
.then(data => {
console.log(data)
})
.catch(err => {
console.log(err)
});
};
if (!apiName !== true) {
uploadAPI()
} else {}
if (!lookupName !== true) {
console.log("Uploading Lookup File");
uploadLookup()
} else {}
I tried using a "setTimeout" function which does not seem to work as I would have liked it to. My best guess is each API call would need to be it's own separate socket connection? Any help with getting me in the right direction is appreciated.
Promise.all([
fetch(url),
fetch(url2)
]).then(function (res) {
// Get a JSON object from each of the responses
return res.json();
}).then(function (data) {
// do something with both sets of data here
console.log(data);
}).catch(function (error) {
// if there's an error, log it
});

Categories