Pass a variable from an array to a Jquery POST method - javascript

I'm trying to pass a variable inside a Jquery POST method from an object array that I get from an asynchronous IndexedDB call using YDN-DB.
Basically db.values, returns an object array of records stored with information I want to send to a PHP script. I can access the ID or any other field of the record set like r[i].id. The only problem is that I can't access it from the inside of the POST's DONE method so I can delete the record by its ID after it was successfully processed by the PHP script.
Below is what I want to achieve, everything works fine, the only problem is when I try to delete the processed record:
var req = db.values('table');
req.done(function(r){
for(i=0;i<r.length;r++){
var post = $.post('myscript.php', {'sale[]': $.toJSON(r[i])});
post.done(function(data){
if(data == 'ok'){
db.remove('table',r[i].id);
}
});
}
});
Is there a way to do this, and get the ID of the processed record to be deleted instead using its array's position?
Thanks!

The problem is that the closure for the callback function captures the same i variable for all iterations, so when the callsbacks are called the value of i has passed the last item of the array. You can wrap the code in the loop inside a function to create a separate i variable for each iteration:
var req = db.values('table');
req.done(function(r){
for(i=0;i<r.length;r++){
(function(i){
var post = $.post('myscript.php', {'sale[]': $.toJSON(r[i])});
post.done(function(data){
if(data == 'ok'){
db.remove('table',r[i].id);
}
});
})(i);
}
});

Related

Adding more than 1 variable to be called on php from a script

I have a code like this (copied from a forum):
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
$("#lets_search").bind('submit',function() {
var ggg = $('#colsrc').val();
$.post('students_query.php' ,{ggg:ggg}, function(data){
$("#search_results").html(data);
});
return false;
});
});
</script>
What it does is submit search query and return results without refresh.
Just to specify and to be clearer:
lets_search - the ID of a form where every data is taken.
colsrc - ID of a dropdown menu
students_query.php - the file where the submit action takes place, and the one that returns results after a query.
search_results - ID of a span tag where the returned results are shown
Everything works fine. My problem here is the variable created (ggg), which gets its value from colsrc, is the only one value being passed to students_query.php. What I want to happen is to pass 2 values to the students_query.php and I don't know which part of the code to edit or how to do it either.
Consider this data to be used:
ggg2 - another variable to be declared.
searchthis - id of another dropdown menu that contains the other value I want to pass to the php file.
I badly need 2 data to be passed on the php file for both of them will be used on a query that will determine the results to be returned. Thank you.
You can add another value in the post function parameters :
$.post('students_query.php' ,{
ggg:ggg,
ggg2: 'something'
}, function(data){
$("#search_results").html(data);
});
JQuery post function accepts the data to be posted as a plain Javascript object or a string in its second parameter. When you want to post multiple values you can pass an object with multiple key:value pairs. In you case the code will look like this:
// $.post( url, data , success callback, expected dataType)
$.post('students_query.php', {
ggg: ggg, // Add a comma here
ggg2: 'value', // Then add other data like this
searchthis: 'another value' // You can keep adding more
}, function(data) {
$("#search_results").html(data);
});

assigning input value to variable

I am trying to assign an input value to a variable that i have retrieved using JSON / PHP from a database. Every time I go to output it I get a blank/null value.
I have created the global variable at the top of the javascript file:
var theAge=0;
function startApplication(){
getData();
getAge();
alert(theAge);
}
function getData(){
$.getJSON('http://www.myphpfile.co.uk/myfile.php', function(data) {
$.each(data, function(key, val) {
$("#userAge").val(val.age);
});
});
}
function getAge(){
theAge = document.getElementById('#userAge').value;
}
So i am creating the variable theAge, grabbing the data from the database and displaying it in an input field, then trying to grab the input value with the getAge function to then alert it to check its worked. Im just getting a blank box. Can anyone see any errors? Thanks.
$.getJSON is an asynchronous call to a remote url, which means the script continues on past that line while a response is being fetched.
By the time your script gets to getAge(); and alert(theAge);, the response has not yet returned, so theAge is still 0.
Whatever you want to do with the value you get from the remote call needs to be passed in as a callback function. You're already passing a function in there (function(data) { $.each...) -- the rest of what you need to have done with that response (for example, getAge() and alerting the value) needs to be handled in there as well.
update
Assign the value and alert it inside the callback:
$.getJSON('http://www.myphpfile.co.uk/myfile.php', function(data) {
$.each(data, function(key, val) {
$("#userAge").val(val.age);
});
theAge = document.getElementById('userAge').value;
alert(theAge);
});

Javascript global variable not modified in a callback

I'm trying to loop through every 1000 elements in a S3 bucket. This is because 1000 elements in the maximum returned by a get request. If there are more than 1000 elements, it get paginated, and the get request returns with a field call IsTruncated as true, and a marker (NextMarker) element to pass to the next call, letting the next get request start at the next 1000 elements.
I'm getting the data from the get request as a parameter in a callback function, and attempting to store the two pieces of above information in global variables for use in an outer loop. However, the outer loop goes off to infinity because the global variables are never modified in my get request callback function. I've tried using window.variable inside the callback to no avail. Could anyone help me restructure this code to accomplish my goals?
Thanks
Outter loop is commented out for debugging purposes. There are a number of debugging console.log statement I used to determined the root of the problem.
<script type="text/javascript">
s3_bucket = "link_to_s3_bucket";
var go = true;
var marker = "";
//while(go){
console.log('pass');
console.log(s3_bucket + marker);
$.get(
s3_bucket+marker,
"{}",
function(data) {
$(data).find('Key').each(function(i, key) {
key = key.innerHTML;
$("<a />", {
href : s3_bucket+key,
text : key
}).prependTo("#links");
$("<br />").prependTo("#links");
});
window.go = $(data).find('IsTruncated')[0].innerHTML;
window.marker = "&marker=" + $(data).find('NextMarker')[0].innerHTML;
},
"xml"
);
//}
console.log(go);
console.log(marker);
</script>
Your data returns asynchronously from Amazon, so those variables haven't been defined yet when you call those console logs. Put the console logs inside of the callback after the variable assignments.

Pass additional parameter to a JSONP callback

For a project of mine I need to do multiple calls to a (remote) API using JSONP for processing the API response. All calls use the same callback function. All the calls are generated dynamically on the client's side using JavaScript.
The problem is as follows: How do I pass additional parameters to that callback function in order to tell the function about the request parameters I used. So, e.g., in the following example, I need the myCallback function to know about id=123.
<script src="http://remote.host.com/api?id=123&jsonp=myCallback"></script>
Is there any way to achieve this without having to create a separate callback function for each of my calls? A vanilla JavaScript solution is preferred.
EDIT:
After the first comments and answers the following points came up:
I do not have any control over the remote server. So adding the parameter to the response is not an option.
I fire up multiple request concurrently, so any variable to store my parameters does not solve the problem.
I know, that I can create multiple callbacks on the fly and assign them. But the question is, whether I can avoid this somehow. This would be my fallback plan, if no other solutions pop up.
Your options are as follows:
Have the server put the ID into the response. This is the cleanest, but often you cannot change the server code.
If you can guarantee that there is never more than one JSONP call involving the ID inflight at once, then you can just stuff the ID value into a global variable and when the callback is called, fetch the id value from the global variable. This is simple, but brittle because if there are every more than one JSONP call involving the ID in process at the same time, they will step on each other and something will not work.
Generate a unique function name for each JSONP call and use a function closure associated with that function name to connect the id to the callback.
Here's an example of the third option.
You can use a closure to keep track of the variable for you, but since you can have multiple JSON calls in flight at the same time, you have to use a dynamically generated globally accessible function name that is unique for each successive JSONP call. It can work like this:
Suppose your function that generate the tag for the JSONP is something like this (you substitute whatever you're using now):
function doJSONP(url, callbackFuncName) {
var fullURL = url + "&" + callbackFuncName;
// generate the script tag here
}
Then, you could have another function outside of it that does this:
// global var
var jsonpCallbacks = {cntr: 0};
function getDataForId(url, id, fn) {
// create a globally unique function name
var name = "fn" + jsonpCallbacks.cntr++;
// put that function in a globally accessible place for JSONP to call
jsonpCallbacks[name] = function() {
// upon success, remove the name
delete jsonpCallbacks[name];
// now call the desired callback internally and pass it the id
var args = Array.prototype.slice.call(arguments);
args.unshift(id);
fn.apply(this, args);
}
doJSONP(url, "jsonpCallbacks." + name);
}
Your main code would call getDataForId() and the callback passed to it would be passed the id value like this followed by whatever other arguments the JSONP had on the function:
getDataForId(123, "http://remote.host.com/api?id=123", function(id, /* other args here*/) {
// you can process the returned data here with id available as the argument
});
There's a easier way.
Append the parameter to your url after '?'. And access it in the callback function as follows.
var url = "yourURL";
url += "?"+"yourparameter";
$.jsonp({
url: url,
cache: true,
callbackParameter: "callback",
callback: "cb",
success: onreceive,
error: function () {
console.log("data error");
}
});
And the call back function as follows
function onreceive(response,temp,k){
var data = k.url.split("?");
alert(data[1]); //gives out your parameter
}
Note: You can append the parameter in a better way in the URL if you already have other parameters in the URL. I have shown a quick dirty solution here.
Since it seems I can't comment, I have to write an answer. I've followed the instructions by jfriend00 for my case but did not receive the actual response from the server in my callback. What I ended up doing was this:
var callbacks = {};
function doJsonCallWithExtraParams(url, id, renderCallBack) {
var safeId = id.replace(/[\.\-]/g, "_");
url = url + "?callback=callbacks." + safeId;
var s = document.createElement("script");
s.setAttribute("type", "text/javascript");
s.setAttribute("src", url);
callbacks[safeId] = function() {
delete callbacks[safeId];
var data = arguments[0];
var node = document.getElementById(id);
if (data && data.status == "200" && data.value) {
renderCallBack(data, node);
}
else {
data.value = "(error)";
renderCallBack(data, node);
}
document.body.removeChild(s);
};
document.body.appendChild(s);
}
Essentially, I compacted goJSONP and getDataForUrl into 1 function which writes the script tag (and removes it later) as well as not use the "unshift" function since that seemed to remove the server's response from the args array. So I just extract the data and call my callback with the arguments available. Another difference here is, I re-use the callback names, I might change that to completely unique names with a counter.
What's missing as of now is timeout handling. I'll probably start a timer and check for existence of the callback function. If it exists it hasn't removed itself so it's a timeout and I can act accordingly.
This is a year old now, but I think jfriend00 was on the right track, although it's simpler than all that - use a closure still, just, when specifying the callback add the param:
http://url.to.some.service?callback=myFunc('optA')
http://url.to.some.service?callback=myFunc('optB')
Then use a closure to pass it through:
function myFunc (opt) {
var myOpt = opt; // will be optA or optB
return function (data) {
if (opt == 'optA') {
// do something with the data
}
else if (opt == 'optB') {
// do something else with the data
}
}
}

How do I display values of an JSON object?

Here is what I got so far. Please read the comment in the code. It contains my questions.
var customer; //global variable
function getCustomerOption(ddId){
$.getJSON("http://localhost:8080/WebApps/DDListJASON?dd="+ddId, function(opts) {
$('>option', dd).remove(); // Remove all the previous option of the drop down
if(opts){
customer = jQuery.parseJSON(opts); //Attempt to parse the JSON Object.
}
});
}
function getFacilityOption(){
//How do I display the value of "customer" here. If I use alert(customer), I got null
}
Here is what my json object should look like: {"3":"Stanley Furniture","2":"Shaw","1":"First Quality"}. What I ultimately want is that, if I pass in key 3, I want to get Stanley Furniture back, and if I pass in Stanley Furniture, I got a 3 back. Since 3 is the customerId and Stanley Furniture is customerName in my database.
If the servlet already returns JSON (as the URL seem to suggest), you don't need to parse it in jQuery's $.getJSON() function, but just handle it as JSON. Get rid of that jQuery.parseJSON(). It would make things potentially more worse. The getFacilityOption() function should be used as callback function of $.getJSON() or you need to write its logic in the function(opts) (which is actually the current callback function).
A JSON string of
{"3":"Stanley Furniture","2":"Shaw","1":"First Quality"}
...would return "Stanley Furniture" when accessed as follows
var json = {"3":"Stanley Furniture","2":"Shaw","1":"First Quality"};
alert(json['3']);
// or
var key = '3';
alert(json[key]);
To learn more about JSON, I strongly recommend to go through this article. To learn more about $.getJSON, check its documentation.
getJSON will fire an asynchronous XHR request. Since it's asynchronous there is no telling when it will complete, and that's why you pass a callback to getJSON -- so that jQuery can let you know when it's done. So, the variable customer is only assigned once the request has completed, and not a moment before.
parseJSON returns a JavaScript object:
var parsed = jQuery.parseJSON('{"foo":"bar"}');
alert(parsed.foo); // => alerts "bar"
.. but, as BalusC has said, you don't need to parse anything since jQuery does that for you and then passes the resulting JS object to your callback function.
var customer; //global variable
function getCustomerOption(ddId){
$.getJSON("http://localhost:8080/WebApps/DDListJASON?dd="+ddId, function(opts) {
$('>option', dd).remove(); // Remove all the previous option of the drop down
if(opts){
customer = opts; //Attempt to parse the JSON Object.
}
});
}
function getFacilityOption(){
for(key in costumer)
{
alert(key + ':' + costumer[key]);
}
}

Categories

Resources