function addItemToCart (id_1, id_2, id_3, id_etc) {
jQuery.ajax({
});
}
function clearCart()
{
jQuery.ajax({
});
}
function buyButton()
{
clearCart();
setTimeout(function()
{
redirect to cart;
addItemToCart(283746 , 1, 1, "Months", "1294");
}, 500);
}
I'm trying to make it so that instead of using a setTimeout it waits until the clearCart() has finished loading through ajax and then it runs the functions inside the setTimeout and I can't seem to figure this out.. I tried doing a callback but I'd say that it isn't correct..
function FirstFunction(callBack)
{
clearCart();
if (callback)
{
callback();
}
}
function SecondFunction()
{
buyButton();
}
FirstFunction(SecondFunction);
If you want to run some code when an Ajax response has arrived, put it in the done or success handler function. That is what those functions are for.
Don't guess how long the request is going to take.
Need to use done or success callback to avoid any random waiting time. like below:
function clearCart()
{
return jQuery.ajax({
});
}
function buyButton()
{
clearCart().done(function () {
addItemToCart(283746 , 1, 1, "Months", "1294");
});
}
Related
I have been trying to load several CSV files before running the code on my page as it uses the data from the CSV files. I have used PAPAPARSE.js as a library to help me with this and I have come up with the following solution.
function loadData(){
console.log("Loading Data!")
loadNodeData();
loadEdgeData();
loadHeadendData();
setup();
}
function loadNodeData(){
Papa.parse("Data/CSV1.csv", {
download: true,
step: function(row) {
NodeData.push(row.data)
},
complete: function() {
console.log("Loaded Node Data!");
load1 = true;
}
});
}
function loadEdgeData(){
Papa.parse("Data/CSV2.csv", {
download: true,
step: function(row) {
EdgeData.push(row.data)
},
complete: function() {
console.log("Loaded Edge Data!");
load2 = true;
}
});
}
function loadHeadendData(){
Papa.parse("Data/CSV3.csv", {
download: true,
step: function(row) {
HeadendArr.push(row.data)
},
complete: function() {
console.log("Loaded Headend Data!");
load3=true;
}
});
}
function setup() {
intervalID = setInterval(isDataLoaded,100)
}
function isDataLoaded(){
//Attempt to setup the page, this will only work if the data iss loaded.
if(load1 && load2 && load3){
console.log("LOADED");
_setupSearchOptions();
}
}
I have this following setup, however i don't know if this is the best way to go about doing something like this. the loadData triggers on page load
<head onload="loadData()">
Is this the correct way to make the program flow?
A more modern approach is to use promises.
You can cut down the code repetition by creating one function that passes in the url and step array to push to and wrap the Papa.parse() call in a promise that gets resolved in the complete callback.
Then use Promise.all() to call _setupSearchOptions() after all three promises resolve
Something like:
function parseCsv(url, stepArr){
return new Promise(function(resolve, reject){
Papa.parse(url, {
download:true,
step: function(row){
stepArr.push(row.data)
},
complete: resolve
});
});
}
function loadData(){
const nodeReq = parseCsv("Data/CSV1.csv", NodeData);
const edgeReq = parseCsv("Data/CSV2.csv", EdgeData);
const headReq = parseCsv("Data/CSV3.csv", HeadendArr);
Promise.all([ nodeReq, edgeReq, headReq]).then(_setupSearchOptions);
}
Note that no error handling has been considered here. Presumably the Papa.parse api also has some fail or error callback that you would use to call the reject() and use a catch() with Promise.all() to handle that failure
I am new to node and the async way of doing things.
I want to create and run a test suite using nightwatch.js, I have read all the docs and I'm baffled at how to do what I want (been working on it for 3 days already).
Am I thinking about this the wrong way?
module.exports = {
before: function(browser) {
/*
Here I just want to make a web call to an api and get a result and then
store that result in a variable which we will use later in test1 and other test cases
*/
browser.globals.myVariable = resultofsomeapicalll;
//wait here until proceeding
},
after: function(browser) {
browser.end();
},
beforeEach: function(browser) {
},
afterEach: function() {
},
'test1': function(browser) {
browser.url(browser.launchUrl + browser.globals.myVariable, function(result) {
browser.waitForElementPresent('body', 1000);
browser.expect.element("#something").to.be.present;
browser.saveScreenshot('./screenshots/' + browser.currentTest.module + '/' + browser.currentTest.name + '.png');
});
},
};
To perform asynchronous task in the Nightwatch.JS before[Each] or after[Each] hooks, you need to pass an callback argument to the function, which you trigger once the job is done.
In below example, it would be an API Call using Axios library;
module.exports = {
before: function(browser, done) {
axios.get('https://example.com/api?ID=12345')
.then(function (response) {
browser.globals.myVariable = response;
done();
})
.catch(function (error) {
done(error);
});
},
after: function(browser) {
browser.end();
},
beforeEach: function(browser) {
},
afterEach: function() {
},
'test1': function(browser) {
console.log()
},
};
Controlling the done invocation timeout
By default the done invocation timeout is set to 10 seconds (2 seconds
for unit tests). In some cases this might not be sufficient and to
avoid a timeout error, you can increase this timeout by defining an
asyncHookTimeout property (in milliseconds) in your external globals
file (see below for details on external globals).
http://nightwatchjs.org/guide/#asynchronous-before-each-and-after-each-
Best regards,
Riku
I am having an issue with $.ajax, $.when and apply. I have a constructor:
The ajax request is not triggered when it should be :
http://plnkr.co/edit/Ul9d8tB7BHoZyHzzQQyB?p=preview
(see the console)
function updateGeneralTerm() {
return {
id: "GeneralCondition",
ajax: function () {
return $.ajax({
type: 'POST',
url: "#Url.Action("UpdateGeneralTerms", "Agreements")",
data: $("#GeneralConditions").serialize()
})
}
}
}
//I inject it in my custom function
function CustomFunction(arr) {
let arrOfAjax = arr.map(function (obj) {
return obj.ajax
});
$.when.apply(null, arrOfAjax);
}
CustomFunction([new updateGeneralTerm()];
In my CustomFunction, I am checking other stuff, as does the form has changed... etc. However it doesn't seem to be relevant for my issue. Nothing happens.
In the future I might have n specific term that I'd like to update only if forms has changed.
My issue: ajax are not requested by $.when(). If I am changing to return obj.ajax(), the ajax request is triggered there directly not by the $.when().
I 'd like the $.when() to handle all ajax requests.
http://plnkr.co/edit/Ul9d8tB7BHoZyHzzQQyB?p=preview
try to rewrite your CustomFunction function to use spread operator:
function CustomFunction(arr) {
let arrOfAjax = arr.map(function (obj) {
return obj.ajax
});
$.when(...arrOfAjax).then(function(...results) {
console.log(results);
});
}
I need to figure out how to call this function synchronously.
fetchData: function(recs){
store = Ext.getStore('OutOfBalanceList');
store.reload({
params: {
startDate: searchForm.startDate,
endDate: searchForm.endDate,
cusip: searchForm.cusip,
account: searchForm.account
},
callback: function (records, options, success) {
recs = records.length;
return recs;
}
});
},
I appreciate all the sermons about Async, but in this case I have to use Synchronous calls because when the data returned is empty, I have to call back again with different parameters. Presently this ends up being an infinite loop because "recs" is not changed outside!
Many thanks
Don't try and make it synchronous. Do the "call again with different parameters" inside your callback method. Something like this:
fetchData: function(recs) {
var me = this;
store = Ext.getStore('OutOfBalanceList');
store.reload({
params: {
startDate: searchForm.startDate,
endDate: searchForm.endDate,
cusip: searchForm.cusip,
account: searchForm.account
},
callback: function (records, options, success) {
if (records.length == 0) {
me.fetchDataWithDifferentParameters();
}
}
});
}
If you're going to work with JavaScript frameworks and calls to external data sources, then learning how to use callbacks is pretty darn important.
I wanted to be able to run two tasks inside async each function using the "async module".
for example:
async.each(openFiles, function( file, callback) {
// task 1
function(){
callback();
}
function(){
callback(); // task 2, waits for task 1 to finish
}
}, function(err){
console.log("done");
});
Im using each because Im looping through each value and need apply two asks to each element.
You should be able to run async.series inside async.each. This will iterate openfiles and run the series inside, it will only then progress through the each loop when series has finished.
async.each(openFiles, function(file, eachCallback) {
async.series([
function(seriesCallback) {
seriesCallback();
},
function(seriesCallback) {
seriesCallback();
}
], function() {
eachCallback();
})
}, function(err) {
console.log("done");
});
Here is some code for the 2-async approach:
async.each(openFiles, function( file, callback) {
async.each([task1, task2], function(task, cb) {
task(file); // exec tasks 1, 2
cb(); // one completed
}, callback); // both completed
}, function(err){
console.log("done");
});
You can make use of javascript callback over here to create dependency of task1 on task2. Something like this:
async.each(openFiles, function( file, callback) {
// task 1
function task1(function(){
function task2 (function(){
//callback of async
callback();
});
});
}, function(err){
console.log("done");
});
and your task 1 and task 2 function will take the callback as an argument something like this:
function task1(callback){
//do whatever in task1
callback();
}
function task2(callback){
//do whatever in task1
callback();
}
In this way task2 will run only when task1 is complete inside async.each