Fairly new to Javascript. I've got a HTML form with onsubmit attribute equal to my JavaScript function getResponse(). In the getResponse() function I do a fetch (POST) to retrieve data from my API. I want to append the data to the page for the user to see, however, it seems to get wiped from the screen within milliseconds of it appearing on the screen.
My function getResponse():
fetch('/', {
method: "POST",
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json',
},
})
.then(json)
.then(function (data) {
$(".formResponse").append(`<p>Response: ${data.user}`)
})
.then(function (error) {
console.error(error);
});
It's a similar situation to if I console log the data it will disappear unless I 'preserve' the log in dev tools. Any suggestions, what am I doing wrong here?
You need to prevent the default behavior of the form submitting. you can do this by calling preventDefault() on the event passed from onsubmit:
function getResponse(event) {
// Prevent the default behavior of the form submitting.
event.preventDefault()
fetch('/', {
method: "POST",
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json',
},
})
.then(json)
.then(function (data) {
$(".formResponse").append(`<p>Response: ${data.user}`)
})
.then(function (error) {
console.error(error);
});
}
The <form> onsubmit is passed an event argument, so you would then do the following on your form:
<form onsubmit="getResponse(event);"></form>
I can't quite see from this code why the data would disappear.
You should use a GET method to retrieve data. POST is used to create a record or save something.
The CRUD methods associated with http requests are the following.
GET / RETRIEVE - to retrieve data from a remote server. Like 'Open'.
POST / CREATE - to save or create data to a database. Like 'Save As'.
PUT / UPDATE - to update or save extra data to an already existing record. Like 'Save'.
DELETE / DESTROY - to delete a record.
If that doesn't work you might have to add some more of your code so we can see what's going on.
Related
I would like to ask difference between calling Control's action via html FORM and JavaScript.
If I use NetCore calls the Action Method and returns View() obj into View page.
But when I call the same Action, webpage stays in the same page.
For example, you have a Employee List page where all employees are listed and wanted to see on of the specific employees details in Emplpoyee Details page.
With html
<form method='post' action ='EmployeeDetails'> </form> It works and browser opens the new page.
But with Javascript
function postSelectedCustomerData(path, method = 'post') {
let data = {
SearchText: 'SearchText1',
EmpName: '1',
DealsOnly: true,
PageNumber: 1
}
fetch("../Employee/EmployeeDetailsPost", {
method: "POST",
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
}).then(res => {
console.log("Request complete! response:", res);
});
}
NOTE: I know I can redirect the page from fetch Return with window.location.href. But I want to know is there any way i can call action method with JavaScript and return to the action Method page?
When you use standard <form> framework functionality, the server posts back to the client an HTTP response that's being interpreted by the browser as a new web page to be loaded.
When you skip this using a simple javascript fetch, the handling of the response it's all up to you. Just from a DOM point of view (let's suppose you only get '200' response!) you should identify the parent of the existing tree that will be replaced, remove said tree, insert the new one from the response.
fetch("../Employee/EmployeeDetailsPost", {
method: "POST",
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
}).then(res => {
let parent = document.getElementById('parent');
let root = document.getElementById('root');
root.remove();
parent.append(res);
});
}
this is the error
the form is not updating in the DB. It is showing this bellow error
const handleAddItem = (event) => {
event.preventDefault();
const productName = productNameRef.current.value;
const price = priceRef.current.value;
const description = descriptionRef.current.value;
const quantity = quantityRef.current.value;
const img = imgRef.current.value;
// console.log(productName, price, description, quantity, img);
const url = `http://localhost:5000/item`;
fetch(url, {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(event)
})
.then(res=> res.json())
.then(result =>{
console.log(result);
})
}
Here is the code part the handles the submission of the form. and the form is a basic HTML form. This code shows the above mention error snipit that includes the error. Please need some help to solve this. Thank you..
As the error notes in your screenshot, you have a circular dependency in the JSON object you are trying to stringify.
If you notice, the event parameter you're receiving in your handleAddItem method is actually an HTML Event (it could be a KeyboardEvent or a MouseClickEvent or a PointerEvent..etc). Events carry a lot of information on them, including information about the element being interacted with. That information about the element can include circular dependencies as element references can ultimately include references back to themselves.
It looks like in your case, since you're working within React, the information provided by React Fiber (react's underlying algorithm) that is stored in the event, on a field called stateNode, includes a circular reference back to itself when you do JSON.stringify(event).
What should you do instead
You should avoid trying to stringify an event and instead use local state (via useState or your useRef refs you have like product name..etc) and construct an object instead to send to your API like so:
fetch(url, {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
productName, price, description, quantity, img})
})
You don't need to send an HTML event to your API; you should work with clean object/json data that contains exactly what you need.
I want to post with the Fetch API and call an action from my controller but the action is not being loaded like when I would do it with submitting a post form.
function postQuery() {
let query = document.getElementById("query").value;
fetch('/actionName', {
method: 'POST',
body: query,
headers:
{
"Content-Type": "application/x-www-form-urlencoded"
}
})
.then(response => {
console.log(response);
})
.then(data => {
console.log('Success:', data);
})
}
/actionName is not being loaded, I am supposed to be directed to a different page.
When I would submit a form like that:
<form action="/actionName" method="post">
the public function actionName would be called but with fetch its not working.
When i try to see the $_POST with var_dump($_POST) inside of actionName, I am getting an empty array...I dont understand this
I see two questions here:
Why is the data not accessible to the server
Why is the brower not redirected to /actionName
Answer to #1:
Make sure the content type header matches the data you are sending, if it is raw json, you should use application/json rather then application/x-www-form-urlencoded. If you want to send a form using fetch API, you would need to either serialize to form to a URL encoded format, or use FormData, for example:
var fd = new FormData(document.getElementById('myForm'))
fetch('/actionName', {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data;'
},
body: fd
})
Answer to #2:
Submitting HTML Forms will direct the browser to the forms action, so if I submit a form to /actionName, I will end up seeing the HTML that is returned by the server for that route. Using Fetch API to submit a form is a type of AJAX, which means that it is capable of communicating with the server without needing to load a new page.
With that in mind, you have a few options:
Use a regular form so that the desired default behavior happens
Manually redirect the user somewhere after the fetch promise resolves, something like:
fetch(/*..*/).then(data => {
console.log('Success:', data);
window.location.href = '/otherPage'
})
Render the response HTML without redirecting the user, something like:
fetch(/*..*/).then(data => {
console.log('Success:', data);
data.text().then(rawHTML => {
document.body.parentElement.innerHTML = rawHTML
})
})
My personal intuition would be to go with the first option, as it suits your requirements and is the simplest.
I created a JavaScript Bot using BotFramework and Botbuilder-js.
For this bot I use an adaptive dialog.
At some point in the dialog I need to send an HTTP-request.
For now, my HTTP-request Step looks like this:
new HttpRequest().configure({
resultProperty: new StringExpression("user.teamProfile.accessToken"),
url: new StringExpression('https://login.microsoftonline.com/myTenantId/oauth2/v2.0/token'),
method: HttpMethod.POST,
contentType: new StringExpression('application/x-www-form-urlencoded'),
headers: {
"Content-Type": new StringExpression("application/x-www-form-urlencoded")
},
body: new StringExpression("client_id: myClientId, scope: https://graph.microsoft.com/.default, client_secret: myclientSecret, grant_type: client_credentials"),
responseType: ResponsesTypes.Json
})
The bot in itself is working but when it tries to execute the HTTP-Request step, I get the following error message:
Error: TypeError: path.indexOf is not a function
Unfortunately, I don't get any more information. Can anyone help me ?
Best regards,
BufferOverflow
Since the HttpRequest-Step didn't work, I changed to a CodeAction.
Inside this CodeAction I then do my Http-Requests and work on the results (transforming them or saving them in a dialog variable).
A Code Snippet could look like the following:
new CodeAction(async (dc, options) => {
// Send your request
// options being the headers, body, etc.
const response = await this.fetch(url, options);
// Work on you result and if necessary, save it to a dialog variable
dc.state.setValue("user.yourPropertyName", value);
// Needed for the Bot to continue working
return await dc.endDialog();
})
I am trying to build the following and I am learning JS as I go, so I would appreciate some guidance and explanation on how to approach the following:
I have two pages, one with client-side script, that takes an uploaded image, converts it to base64 and fetches it to the second page, where the server-side script uploads it to a location via API.
This is the fetch on my first page:
fetch("xxxxxx", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
fileEnc: fileEnc,
fileName: fileName,
fileType: fileType
})
})
.then(function (res) {
console.log("Success!", res);
})
.catch(function (err) {
console.log("Error!", err);
});
};
On my second page, an API call is made and I get the following response:
console.log(uploadImage.StatusCode)
My question is:
How do I pass the response back to my first page and how do I display it?
Thanks
Second page should write the status code in the response rather than in the console. And that text will be available in the "then" part of the fetch function.
assuming that the second page was opened from the first page, write a function in the first page where you want to consume that data which is executed from the second page with the data you need as an argument:
page 1
function logData(data) {
console.log('#data from api: ', data)
}
page2
// some code here
window.opener.logData(dataFromApi)