Undo preventDefault() after API call - javascript

I am writing external script to check availability for e-commerce store. When "Add to basket" button is pressed, I'm calling my API and checking if product is available to order. However, I don't know how to undo preventDefault(). When condition is true, event under button should continue and product should be added to basket as without the script.
button.addEventListener('click', (event) => {
event.preventDefault();
fetch(`https://example.com/api.php?part=${partId}`)
.then(function (response) {
return response.json();
})
.then(function (jsonRes) {
console.log(JSON.stringify(jsonRes));
if (jsonRes.part.partFound == true) {
console.log('Found! Processing...');
// REMOVE preventDefault() and process
} else {
console.log('Not found! Aborting...', partId);
}
});
});

If your button is type="submit" change it totype="button"`. This
a) Won't submit the form
b) Means that you don't have to use preventDefault to prevent the form from submitting
That simply means you're left to decide how you want the data to be submitted, and you can either do that with another AJAX call to an API endpoint, or by submitting the whole form to the server - whichever is your setup.
// Grab the form and button, and add an event
// listener to the button
const form = document.querySelector('form');
const button = document.querySelector('button');
button.addEventListener('click', handleClick, false);
// Fake API call
function fakeAPI() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`API called!`)
}, 2000);
});
}
function handleClick() {
console.log('Clicked');
fakeAPI(2000).then(data => {
// If partfound submit the form data
// Either another fetch call to post the data,
// or `form.submit()` to post the whole form instead
});
}
<form>
<button type="button">
Click
</button>
</form>

you can try something like code below:
async function apiCall(onSuccess, onError) {
fetch(`https://example.com/api.php?part=${partId}`)
.then(function (response) {
return response.json();
})
.then(function (jsonRes) {
console.log(JSON.stringify(jsonRes));
if (jsonRes.part.partFound == true) {
console.log('Found! Processing...');
onSuccess(jsonRes);
} else {
console.log('Not found! Aborting...', partId);
onError();
}
});
}
button.addEventListener('click', (event) => {
// show loading or something
apiCall(function (response) {
// success
}, function () {
// error
});
});

Related

When the user changes the button onClick again executes

When I have not yet signed in and I click the button : it gives alert to login first
And after that as soon as I login with google (via firebase auth) then the script again executes and this time it executes as logged in function and pushes me to another page...
<Button
key={q}
id={q}
onClick={handleClick}
>
some Text
</Button>
And here is handleClick function:-
const handleClick = (e) => {
e.preventDefault();
let name = e.target.offsetParent.id;
firebase.auth().onAuthStateChanged(function (user) {
if (user) {
history.push("/testPage/" + btoa(name));
}else{
window.alert("Login To Continue");
}
});
};
Before signing in when I click the button the else statement executes... but as soon as I sign in then without clicking any button the if statement executes.
How do I remove the second execution i.e. once I click the button it gives me response and after I login, it should not again give me a response untill I again click it.
You are subscribing to an observable. Every time the observable fires your observer is called. You can store the subscription returned by the function to unsubscribe. Or you could just not subscribe to an observable and use the property:
const handleClick = (e) => {
e.preventDefault();
let name = e.target.offsetParent.id;
const user = firebase.auth().currentUser;
if (user) {
history.push("/testPage/" + btoa(name));
}else{
window.alert("Login To Continue");
}
};

Trigger click event of dynamic loaded content from ajax call

Unable to trigger click event for an dynamically loaded content from ajax call. Tried to use trigger method but guess I am missing something here.
$("#call-setup").on("click", function () {
var $this = $("#settings")
var url = $this.data("link")
loadwifinetworks(url);
//$("#connectivity").trigger("click")
});
async function loadwifinetworks(url) {
await new Promise((resolve) => {
$.get(url, function (context) {
$("#contentArea").html(context);
resolve("success")
});
});
//$('body').find('#connectivity').trigger('click');
// $('#contentArea').find('#connectivity').trigger("click")
}

jQuery - trigger("click") not working after e.preventDefault()

I'm trying to perform async operation right before browser redirects user to http://example.com on click.
So, after the ajax call I'm clicking currentTarget again to redirect but it doesn't work.
<a class="notic_click" href="http://example.com">Button</a>
<a class="notic_click" href="http://example.com">Button</a>
$(".notic_click").on("click", function(e, options) {
options = options || {};
// if it hasn't been clicked already
// run this
if( !options.hasClicked ) {
e.preventDefault();
const self = this;
// some other code
$.get("http://example.com/hello")
.always(function() {
$(self).trigger("click", {hasClicked: true});
});
} else {
// I got here, that means e.preventDefault didn't get called and it should redirect
console.log("should redirect but not redirecting");
}
});
I tried $(self).off() right before the trigger, but to no avail.
I have already tried this:
window.location.assign(e.target.href);
and this works. But I'm curious as to what is causing the above not to work.
Browser: Mozilla Firefox (78.0.2)
try this out:
$(".notic_click").on("click", function(e) {
if( e.isTrusted) {
e.preventDefault();
const self = this;
// some other code
$.get("http://example.com/hello")
.always(function() {
$(self).click();
});
} else {
// I got here, that means e.preventDefault didn't get called and it should redirect
console.log("should redirect but not redirecting");
}
});
You can read more about is trusted here: https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted
Try it with this code piece. You seem to have a logic problem in your code. Since you prevent the default, you should "return" to the default behaviour:
<a class="notic_click" href="http://example.com">Button</a>
<a class="notic_click" href="http://example.com">Button</a>
<script>
$(".notic_click").on("click", async function (e, options) {
options = options || {};
e.preventDefault();
console.log('do task here');
await new Promise(resolve => setTimeout(resolve, 3000));
console.log('timeout end');
await new Promise(resolve => setTimeout(resolve, 3000));
window.location = this.href;
});
</script>
Your code appears to work fine in isolation. That being said, a better approach would be to always call preventDefault() to stop the page redirection and then make your async AJAX request. When that request completes you can then use window.location.assign() to redirect the user.
$(".notic_click").on("click", e => {
e.preventDefault();
// I'd suggest putting a loading spinner in the UI here to make it clear
// to the user that their request is in process.
$.get("http://example.com/hello").always(() => {
window.location.assign(e.target.href);
});
});

Javascript- How to check if operation has been completed on this event

Is there any way to check if the event is completed and element is free to perform another action?
Like I want to do
$('#button-cancel').on('click', function() {
// send ajax call
});
/****************************************
extra code
*******************************************/
$('#button-cancel').on('click', function() {
if(ajax call is completed) {
//do some thing
}
});
I don't want to send ajax call in second onclick as it is already been sent, just want to check if it is done with ajax then do this
You can introduce a helper variable:
// introduce variable
var wasAjaxRun = false;
$('#button-cancel').on('click', function() {
// in ajax complete event you change the value of variable:
$.ajax({
url: "yoururl"
// other parameters
}).done(function() {
// your other handling logic
wasAjaxRun = true;
});
});
$('#button-cancel').on('click', function() {
if(wasAjaxRun === true) {
//do some thing
}
});
EDIT: I just noticed that you have event handlers attached to the same button. In that case my initial answer would not work, because first event hander would be executed every time you click the button.
It is not very clear from the description what you want to do with your first event hander. I assume you want to use some data, and if you already have this data, then you use it immediately (like in second handler), if you don't have it - you make the AJAX call to get the data (like in first handler).
For such scenario you could use single event handler with some conditions:
var isAjaxRunning = false; // true only if AJAX call is in progress
var dataYouNeed; // stores the data that you need
$('#button-cancel').on('click', function() {
if(isAjaxRunning){
return; // if AJAX is in progress there is nothing we can do
}
// check if you already have the data, this assumes you data cannot be falsey
if(dataYouNeed){
// You already have the data
// perform the logic you had in your second event handler
}
else { // no data, you need to get it using AJAX
isAjaxRunning = true; // set the flag to prevent multiple AJAX calls
$.ajax({
url: "yoururl"
}).done(function(result) {
dataYouNeed = result;
}).always(function(){
isAjaxRunning = false;
});
}
});
You should be able to provide handlers for AJAX return codes. e.g
$.ajax({
type: "post", url: "/SomeController/SomeAction",
success: function (data, text) {
//...
},
error: function (request, status, error) {
alert(request.responseText);
}
});
you can disable the button as soon as it enters in to the event and enable it back in ajax success or error method
$('#button-cancel').on('click', function() {
// Disable button
if(ajax call is completed) {
//do some thing
//enable it back
}
});
This is edited, more complete version of dotnetums's answer, which looks like will only work once..
// introduce variable
var ajaxIsRunning = false;
$('#button').on('click', function() {
// check state of variable, if running quit.
if(ajaxIsRunning) return al("please wait, ajax is running..");
// Else mark it to true
ajaxIsRunning = true;
// in ajax complete event you change the value of variable:
$.ajax({
url: "yoururl"
}).done(function() {
// Set it back to false so the button can be used again
ajaxIsRunning = false;
});
});
You just need to set a flag that indicates ajax call is underway, then clear it when ajax call returns.
var ajaxProcessing = false;
$('#button-cancel').on('click', function(){
processAjaxCall();
});
function processAjaxCall() {
if(ajaxProcessing) return;
ajaxProcessing = true; //set the flag
$.ajax({
url: 'http://stackoverflow.com/questions/36506931/javascript-how-to-check-if-operation-has-been-completed-on-this-event'
})
.done(function(resp){
//do something
alert('success');
})
.fail(function(){
//handle error
alert('error');
})
.always(function(){
ajaxprocessing = false; //clear the flag
})
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button-cancel">Cancel</button>
What you can do is call a function at the end of an if statement like
if(ajax call is completed) {
checkDone();
}
function checkDone() {
alert("Done");
}

submit search query if conditions are met

How would I go about integrating these two functions together so that when submitting the search form, it will first check the http get response, then depending on whether there was an error or not, either submit the form, or display an error message?
All that I've tried has either made the form not work at all, or not take into account the 'http.get function'.
var http = require("http");
var url = 'http://examplepage.com/';
search.submit(function (event) { // submit search query function
if (searchBox.val().length < 2) {
searchBox.focus();
event.preventDefault();
}
});
http.get(url, function (res) {
res.resume();
// successful - so submit search query
}).on('error', function () {
// unsuccessful - display error message
});
You should probably subscribe on click event for you button that triggers search, the go check the url and inside success handler do
Sample code of Click handler
http.get(url, function (res) {
// successful
if (searchBox.val().length < 2) {
$('your form selector').submit();
}
}).on('error', function () {
// unsuccessful - display error message
});

Categories