How to make multiple calls synchronous in elasticsearch? - ajax

Im creating ajax calls to an elasticsearch server inside a "for" loop. The problem Im facing is that,the responses are not coming in proper sequence, (that is in the order which the clients are generated using for loop). How to make the calls and response synchronous? .

You could do something like this:
$(document).ready(function(){
function extendFuncChain(url, callback) {
func_chain_list.push(function() {
$.ajax({
url : url,
type: 'GET',
contentType:"application/json"
}).done(function(data) {
console.debug(data);
callback();
});
});
}
var func_chain_list = [function() {}];
for(var i=1; i<=4; i++) {
var url = "http://localhost:9200/test_index/doc/" + i;
var callback = func_chain_list.pop();
extendFuncChain(url, callback);
}
func_chain_list.pop()();
});
To test it I set up a simple index with 4 documents like this:
DELETE /test_index
PUT /test_index
POST /test_index/doc/_bulk
{"index":{"_id":1}}
{"name": "doc1"}
{"index":{"_id":2}}
{"name": "doc2"}
{"index":{"_id":3}}
{"name": "doc3"}
{"index":{"_id":4}}
{"name": "doc4"}
Then when I put the javascript in a web page and load it, I get this output in the console (I expanded the last one):
Hopefully you can see how to generalize this to do what you need. The call to extendFuncChain is important, because of the way closures work in JS, and it won't work if you take that out.

Related

How to access RESPONSE data from an AJAX Get in JQuery

This is my first attempt at using an AJAX GET to pull data and it is really causing me a nightmare. I have used POST loads of times and assumed accessing the data would be the same basic process, but no matter what I try I always end up with "Undefined".
This is the code I have been trying to make the GET work in my script;
$(document).ready(function() {
$.ajax({
type: "GET",
url: "/buytoken/public/api/stage?secret=***************",
cache: false,
dataType: "json",
success : function(response){
var len = response.length;
for(var i=0; i<len; i++){
var sold = response[i].progress;
}
alert(sold);
}
});
});
This is then what the response should be;
{
"success": true,
"response": {
"ico": "running",
"total": "8,000,000",
"total_amount": "800,000",
"sold": "1,599,300",
"sold_amount": "159,930",
"progress": 20,
"price": "0.1",
"start": "2022-02-28 00:01:00",
"end": "2022-05-31 00:01:00",
"timezone": "Europe/London",
"min": "500",
"max": "4000000",
"soft": "400000",
"soft_amount": "40,000",
"hard": "800000",
"hard_amount": "80,000"
}
}
The script that I am trying to access is on the same webserver.
It is coming from a third-party piece of software that we are running on the site. The documentation states "Application provides some specific internal live data in JSON"
So, we should be getting JSON back.
I need to access just two pieces of data "sold_amount" and "progress" which I want to load into variables in the Success callback.
I really would be grateful if somebody could explain or better still show me how this is supposed to work because I am really banging me head against the wall on this.
Also, if I need to add any extra bits like error handling then please point that out.
Thanks to anybody who responds to this..

Shopify Predictive Search Ajax Call

I'm quite new to shopify, liquid and all that comes with it.
I try to implement predective search on shopify and I just don't know why I'm not even getting the alert of the Ajax call that is in the following code. I put it in my "theme.liquid" file right above the closing body tag. I assume if it would work, there should be the alert right when opening the page, no? Goki is a vendor, many products are shown when I search for it on my page. My code looks like this:
<script>
jQuery.getJSON("/search/suggest.json", {
"q": "goki",
"resources": {
"type": "product",
"limit": 4,
"options": {
"unavailable_products": "last",
"fields": "title,product_type,variants.title"
}
}
}).done(function(response) {
var productSuggestions = response.resources.results.products;
if (productSuggestions.length > 0) {
var firstProductSuggestion = productSuggestions[0];
alert("The title of the first product suggestion is: " + firstProductSuggestion.title);
}
});
</script>
Any help would be very very much appreciated! Thank you!
I solved it. I created an own variable AjaxData with all the 'resources' parameter before entering the JQuery call. There I don't use the variable to create the url, it's just used to define param in the call, not to change the url. -that's the trick

ckan datastore_search API with multiple filters

I'm calling this dataset:
http://data.edinburghopendata.info/api/action/datastore_search?resource_id=4cfb5177-d3db-4efc-ac6f-351af75f9f92
with an AJAX call :
var data = {
resource_id: '4cfb5177-d3db-4efc-ac6f-351af75f9f92',
filters: '{"BankTypeNa": "Packaging", "BankTypeNa": "Compost Bins"}',
limit : 4757
};
$.ajax({
url: 'http://data.edinburghopendata.info/api/action/datastore_search',
data: data,
dataType: 'jsonp',
success: function(data) {
markers = data.result.records;
showMarkers();
}
});
which is giving results only for the second filter.
http://data.edinburghopendata.info/api/action/datastore_search?resource_id=4cfb5177-d3db-4efc-ac6f-351af75f9f92&filters={%22BankTypeNa%22:%20%22Packaging%22,%20%22BankTypeNa%22:%20%22Compost%20Bins%22}
Is there a way, or another parameter I could use to get both "Packaging" and "Compost Bins" in my search results?
Would be nice if somebody can prove me wrong, but its not possible. In theory you would just put the two values in an array as the value for the BankTypeNa key, e.g.
filters: '{"BankTypeNa": ["Packaging", "Compost Bins"]}'
But this doesn't work for text columns (an SQL error results). It does work for numeric ones [1]. It would be good to submit an issue on that at github.com/ckan/ckan.
I would use the datastore_search_sql endpoint instead, i.e.
var data = {
"resource_id": "4cfb5177-d3db-4efc-ac6f-351af75f9f92",
"sql": "SELECT * FROM \"4cfb5177-d3db-4efc-ac6f-351af75f9f92\" WHERE \"BankTypeNa\" LIKE 'Packaging' OR \"BankTypeNa\" LIKE 'Compost Bins'",
"limit": 4757
};
[1] CKAN: delete a list of records within the DataStore in a single query

Series of httpRequests in Cloud Code

I want to do a series of httpRequests in Cloud Code. Promises seemed to be good for this.
I have the URLs in an array like so:
Parse.Cloud.define("serialRequests", function(request, response) {
var urls = ["http://www.htmldog.com/examples/headings1.html", "http://www.htmldog.com/examples/headings2.html", "http://www.htmldog.com/examples/lists1.html", "http://www.htmldog.com/examples/lists2.html"];
var promise = Parse.Promise.as();
var count = 0;
for (var i = 0; i < urls.length; i++) {
var url = urls[i];
promise = promise.always(function() {
return Parse.Cloud.httpRequest({
url: url,
success: function(httpResponse) {
console.log("Response: " + httpResponse.text);
count++;
},
error: function(httpResponse) {
console.log("Status: " + httpResponse.status);
count++;
}
});
});
}
promise.always(function() {
console.log("Count: " + count);
return response.success();
});
});
Despite count being 4 after running the code, the response is not always of the URL the request was made with:
I2014-07-19T06:11:41.807Z]Response: Response of the first URL in the array
I2014-07-19T06:11:42.084Z]Response: Response of the last URL in the array
I2014-07-19T06:11:42.356Z]Response: Response of the last URL in the array
I2014-07-19T06:11:42.624Z]Response: Response of the last URL in the array
I2014-07-19T06:11:42.640Z]Count: 4
What am I doing wrong? Is there an alternative to my solution?
I'm pretty late to the party, but my guess is that you're overriding promise the way you're calling things, rather than just extending the chain.
Do these need to be run one after another? If not, you should create a new Parse.Promise() for each iteration, and add it to an array. Then, after the for loop, return Parse.Promise.when( arrayOfPromsies ).then() , with the then() containing your last promise call there that returns the count and all that. This requires the order in which your httpRequests get called not actually mattering, just that they all happen, regardless of how many fail, which looks to me what you might want.
If they do need to be run one after another, you'll have to change your implementation to use a helper function, in which you pass the count of your array, the current index, and a reference to your array, and return a call to the function itself, incrementing the index, with a .then() returning a promise from the function.

JSONP pass api key

I've got an arduino uploading sensor data to cosm.com. I made a simple webpage on my local web server to query the cosm.com API and print out the values.
The problem is that if I am not logged into cosm.com in another tab, I get this popup.
The solution is to pass my public key to cosm.com, but I am in way over my head here.
The documentation gives an example of how to do it in curl, but not javascript
curl --request GET --header "X-ApiKey: -Ux_JTwgP-8pje981acMa5811-mSAKxpR3VRUHRFQ3RBUT0g" https://api.cosm.com/v2/feeds/120687/datastreams/sensor_reading
How do I pass my key into the url?:
function getJson() {
$.ajax({
type:'GET',
url:"https://api.cosm.com/v2/feeds/120687/datastreams/sensor_reading",
//This line isn't working
data:"X-ApiKey: -Ux_JTwgP-8pje981acMa5811-mSAKxpR3VRUHRFQ3RBUT0g",
success:function(feed) {
var currentSensorValue = feed.current_value;
$('#rawData').html( currentSensorValue );
},
dataType:'jsonp'
});
}
UPDATE:
It must be possible because hurl.it is able to query the api
http://www.hurl.it/hurls/75502ac851ebc7e195aa26c62718f58fecc4a341/47ad3b36639001c3a663e716ccdf3840352645f1
UPDATE 2:
While I never did get this working, I did find a work around. Cosm has their own javascript library that does what I am looking for.
http://cosm.github.com/cosm-js/
http://jsfiddle.net/spuder/nvxQ2/5/
You need to send it as a header, not as a query string, so try this:
function getJson() {
$.ajax({
type:'GET',
url:"https://api.cosm.com/v2/feeds/120687/datastreams/sensor_reading",
headers:{"X-ApiKey": "-Ux_JTwgP-8pje981acMa5811-mSAKxpR3VRUHRFQ3RBUT0g"},
success:function(feed) {
var currentSensorValue = feed.current_value;
$('#rawData').html( currentSensorValue );
},
dataType:'jsonp'
});
}
It should be much easier to get it to work using CosmJS. It is an officially supported library and provides full coverage of Cosm API.

Resources