I am trying to post data using curl php but the issue I am facing the data saved in Google sheet is always coming undefined. I have used below code which is attached with description and also attached the image url which is showing the value coming from is php script I am using php and curl to send data and trying to savethat data in google sheet.
Image showing undefined value: https://ibb.co/0n5WKdz
PHP SCRIPT
function send_to_url($url, $data)
{
$ch = curl_init($url);
//Set a POST method
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
//curl_setopt($ch, CURLOPT_TIMEOUT, 6);
//Set data to JSON application/json
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$jsonDataEncoded = json_encode($data);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);
//POST to URL
$result = curl_exec($ch);
//Get result from POST if any
$result_post = urldecode(json_encode($result));
curl_getinfo($ch);
curl_close($ch);
return $result;
}
$users =
array("Date"=>"Timestamp","FirstName"=>"John","LastName"=>"Cena","Email"=>"john78#example.com");
send_to_url("GOOGLE_APP_SCRIPT_URL",$users);
GOOGLE SCRIPT
var SHEET_NAME = "DATA";
var SCRIPT_PROP = PropertiesService.getScriptProperties(); // new property service
// If you don't want to expose either GET or POST methods you can comment out the appropriate function
function doGet(e){
return handleResponse(e);
}
function doPost(e){
return handleResponse(e);
}
function handleResponse(e) {
var lock = LockService.getPublicLock();
lock.waitLock(30000); // wait 30 seconds before conceding defeat.
try {
// next set where we write the data - you could write to multiple/alternate destinations
var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
var sheet = doc.getSheetByName(SHEET_NAME);
// we'll assume header is in row 1 but you can override with header_row in GET/POST data
var headRow = e.parameter.header_row || 1;
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow()+1; // get next row
var row = [];
// loop through the header columns
for (i in headers){
if (headers[i] == "Timestamp"){ // special case if you include a 'Timestamp' column
row.push(new Date());
} else { // else use header name to get data
row.push(e.parameter[headers[i]]);
}
}
// more efficient to set values as [][] array than individually
sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
// return json success results
return ContentService
.createTextOutput(JSON.stringify({"result":"success", "row": headRow}))
.setMimeType(ContentService.MimeType.JSON);
} catch(e){
// if error return this
return ContentService
.createTextOutput(JSON.stringify({"result":"error", "error": e}))
.setMimeType(ContentService.MimeType.JSON);
} finally { //release lock
lock.releaseLock();
}
}
function setup() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
SCRIPT_PROP.setProperty("key", doc.getId());
}
Please check my code and provide the solution and let me know where I am making mistake.
In your scripts, I think that your php script works and Google Apps Script is required to be modified a little. So how about this modification?
Modification points:
When a JSON object ({"key1": "value1", "key2": "value2"}) is sent to Web Apps as POST request, e of doPost(e) becomes as follows.
{
"parameter": {},
"contextPath": "",
"contentLength": 36,
"queryString": "",
"parameters": {},
"postData": {
"type": "application/json",
"length": 36,
"contents": "{\"key1\": \"value1\", \"key2\": \"value2\"}",
"name": "postData"
}
}
By this, when you want to retrieve the values from the object, the object is required to be parsed like var postData = JSON.parse(e.postData.contents). It seems that although the data is sent as application/json, the object is not automatically parsed.
About the line of if (headers[i] == "Timestamp"){, your sample image doesn't have Timestamp. I thought that it might be Date.
Modified script:
Please modify as follows.
From:
var row = [];
// loop through the header columns
for (i in headers){
if (headers[i] == "Timestamp"){ // special case if you include a 'Timestamp' column
row.push(new Date());
} else { // else use header name to get data
row.push(e.parameter[headers[i]]);
}
}
To:
var postData = JSON.parse(e.postData.contents);
var row = headers.map(function(e) {return e == "Date" ? new Date() : postData[e]});
Result:
When your php script is run, the values are put to the Spreadsheet as follows.
Note:
When you modified Google Apps Script of Web Apps, please redeploy the Web Apps as new version. By this, the latest script is reflected to the Web Apps.
References:
Web Apps
Taking advantage of Web Apps with Google Apps Script
map()
If I misunderstood your question and this was not the result you want, I apologize.
Related
I want to Auto-Run Script in Google Sheets every time someone registers from my custom form on my website and the Data Entry to the Sheet.
I tried with adding an OnSubmit event on Trigger but it did not work because I don't use Google Forms I use a Script to collect the data from my website.
Here is the Send Emails Script that I want to Auto-Run and send an email each time someone's data comes into the sheet:
function sendMail() {
const emailTemp = HtmlService.createTemplateFromFile("email");
const sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("form1");
const startRow = 2;
const data = sh.getRange(startRow, 2, sh.getLastRow() - 1, sh.getLastColumn() - 1).getValues();
data.forEach((row, i) => {
emailTemp.first = row[2];
emailTemp.last = row[3];
emailTemp.phone = row[9];
let htmlMessage = emailTemp.evaluate().getContent();
let emailSent = row[11];
if (emailSent != "EMAIL_SENT") {
GmailApp.sendEmail(
row[1],
"Thank you!",
"Your email doesn't support HTML.",
{ name: "Email App", htmlBody: htmlMessage });
sh.getRange(startRow + i, 13).setValue("EMAIL_SENT");
}
});
}
Here is the Data Collection Script on my website:
// Variable to hold request
var request;
var url = window.location.href;
$( document ).ready(function() {
$('#url').val(url);
});
console.log(url);
// Bind to the submit event of our form
$("#request-form").submit(function(event){
// Abort any pending request
if (request) {
request.abort();
}
// setup some local variables
var $form = $(this);
// Let's select and cache all the fields
var $inputs = $form.find("input, select, button, textarea");
// Serialize the data in the form
var serializedData = $form.serialize();
// Let's disable the inputs for the duration of the Ajax request.
// Note: we disable elements AFTER the form data has been serialized.
// Disabled form elements will not be serialized.
$inputs.prop("disabled", true);
// Fire off the request to /form.php
request = $.ajax({
url: "https://script.google.com/macros/s/AKfycbwa50RJFxZfnBXQX-LBHR4OD6Lzxb0a2tAclBzGV57nT0XY3WU/exec",
type: "post",
data: serializedData
});
// Callback handler that will be called on success
request.done(function (response, textStatus, jqXHR){
// Log a message to the console
console.log("Hooray, it worked!");
console.log(response);
console.log(textStatus);
console.log(jqXHR);
});
// Callback handler that will be called on failure
request.fail(function (jqXHR, textStatus, errorThrown){
// Log the error to the console
console.error(
"The following error occurred: "+
textStatus, errorThrown
);
});
// Callback handler that will be called regardless
// if the request failed or succeeded
request.always(function () {
// Reenable the inputs
$inputs.prop("disabled", false);
console.log("It's running");
window.location.href = 'success.html';
});
// Prevent default posting of form
event.preventDefault();
});
And here is the Script I have used on the Sheet and Deploy it As Web App, and made it accessable to Anyone, even anonymous.
// 1. Enter sheet name where data is to be written below
var SHEET_NAME = "Leads";
// 2. Run > setup
//
// 3. Publish > Deploy as web app
// - enter Project Version name and click 'Save New Version'
// - set security level and enable service (most likely execute as 'me' and access 'anyone, even anonymously)
//
// 4. Copy the 'Current web app URL' and post this in your form/script action
//
// 5. Insert column names on your destination sheet matching the parameter names of the data you are passing in (exactly matching case)
var SCRIPT_PROP = PropertiesService.getScriptProperties(); // new property service
// If you don't want to expose either GET or POST methods you can comment out the appropriate function
function doGet(e){
return handleResponse(e);
}
function doPost(e){
return handleResponse(e);
}
function handleResponse(e) {
// shortly after my original solution Google announced the LockService[1]
// this prevents concurrent access overwritting data
// [1] http://googleappsdeveloper.blogspot.co.uk/2011/10/concurrency-and-google-apps-script.html
// we want a public lock, one that locks for all invocations
var lock = LockService.getPublicLock();
lock.waitLock(30000); // wait 30 seconds before conceding defeat.
try {
// next set where we write the data - you could write to multiple/alternate destinations
var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
var sheet = doc.getSheetByName(SHEET_NAME);
// we'll assume header is in row 1 but you can override with header_row in GET/POST data
var headRow = e.parameter.header_row || 1;
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow()+1; // get next row
var row = [];
// loop through the header columns
for (i in headers){
if (headers[i] == "Timestamp"){ // special case if you include a 'Timestamp' column
row.push(new Date(), "UTC-7");
} else { // else use header name to get data
row.push(e.parameter[headers[i]]);
}
}
// more efficient to set values as [][] array than individually
sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
// return json success results
return ContentService
.createTextOutput(JSON.stringify({"result":"success", "row": nextRow}))
.setMimeType(ContentService.MimeType.JSON);
} catch(e){
// if error return this
return ContentService
.createTextOutput(JSON.stringify({"result":"error", "error": e}))
.setMimeType(ContentService.MimeType.JSON);
} finally { //release lock
lock.releaseLock();
}
}
function setup() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
SCRIPT_PROP.setProperty("key", doc.getId());
}
Thank you.
If you are sending the data to the web app via POST request from the client, then use the doPost(e) function in your Apps Script to do what you want.
Include the sendMail() function inside your doPost(e) function before it returns.
Example:
before you execute this line
return ContentService.createTextOutput(JSON.stringify({"result":"success", "row": nextRow})).setMimeType(ContentService.MimeType.JSON);
in handleResponse(e) I would have the program execute sendMail(). I would also have 2 different functions for doGet and doPost but that's up to you.
I'm having problems sending data to a Google Spreadsheet via Ajax.
I followed this guide to achieve this: https://medium.com/#dmccoy/how-to-submit-an-html-form-to-google-sheets-without-google-forms-b833952cc175
My own code looks as simple as this:
var data = {"user": "bar"};
var url = 'https://script.google.com/macros/s/AKfycby6BzLifopR36ZBJ2WqDMNsndCYUpHihSOfhomfSRZXcdetvOA/exec';
$('.my-button').on('click', function (e) {
$.ajax({
url: url,
method: "GET",
dataType: "json",
data: data
}).done(
function (__e) {
console.log('Remote sheet updated!', __e);
}
).fail(function (__e) {
console.log('Remote sheet update failed', __e);
});
});
This is what my spreadsheet looks like:
This is the code from the tutorial that goes into the Google scripteditor.
function doGet(e){
return handleResponse(e);
}
// Enter sheet name where data is to be written below
var SHEET_NAME = "DATA";
var SCRIPT_PROP = PropertiesService.getScriptProperties(); // new property service
function handleResponse(e) {
// shortly after my original solution Google announced the LockService[1]
// this prevents concurrent access overwritting data
// [1] http://googleappsdeveloper.blogspot.co.uk/2011/10/concurrency-and-google-apps-script.html
// we want a public lock, one that locks for all invocations
var lock = LockService.getPublicLock();
lock.waitLock(30000); // wait 30 seconds before conceding defeat.
try {
// next set where we write the data - you could write to multiple/alternate destinations
var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
var sheet = doc.getSheetByName(SHEET_NAME);
// we'll assume header is in row 1 but you can override with header_row in GET/POST data
var headRow = e.parameter.header_row || 1;
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow()+1; // get next row
var row = [];
// loop through the header columns
for (i in headers){
if (headers[i] == "Timestamp"){ // special case if you include a 'Timestamp' column
row.push(new Date());
} else { // else use header name to get data
row.push(e.parameter[headers[i]]);
}
}
// more efficient to set values as [][] array than individually
sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
// return json success results
return ContentService
.createTextOutput(JSON.stringify({"result":"success", "row": nextRow}))
.setMimeType(ContentService.MimeType.JSON);
} catch(e){
// if error return this
return ContentService
.createTextOutput(JSON.stringify({"result":"error", "error": e}))
.setMimeType(ContentService.MimeType.JSON);
} finally { //release lock
lock.releaseLock();
}
}
function setup() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
SCRIPT_PROP.setProperty("key", doc.getId());
}
In the code provided by the author of the tutorial all I did is change the sheet name in line 9 to "DATA"
// Enter sheet name where data is to be written below
var SHEET_NAME = "DATA";
...which is the name of the sheet.
The problem is now, when I click "my-button", it gets send successfully, but returns an error object. The error doesn't contain any additional information though. It seems to go into the "catch" section of the Google script, but doesn't inform me of what exactly went wrong. Now I don't even know how to debug this, let alone understand, what went wrong.
I already tried all kinds of weird things like using JSON.stringify, none of that helped. It should work like this anyway, so I have no idea what's the problem here.
I'm trying to write a php and javascript code that's going to behave similarly to the code I have below (I didn't write the code) but I'm a little confused on what's going on in the php and how the two are communicating. I've tried to watch videos and read about php but I'm still pretty confused by it.
Then the javascript makes requests to the php when its buttons are clicked and the php sends information back.
The general function of the php file is it displays the contents of a random file in the http://webster.cs.washington.edu/cse154/services/flashcards/pokemon directory. It can take in a parameter called mode. When the user passes in a mode value of categories it outputs a list of all of the folder names in http://webster.cs.washington.edu/cse154/services/flashcards. Otherwise, it just displays the contents of a random file as before.
I get it on a broad overview but I'm still kind of confused on how the php code is working. Like I said I'm trying to write a code that's going to be quite similar to this so I just am trying to get a better understanding of how php works but all the information i've read hasn't been that helpful.
<?php
# Solution to CSE 154 Flashcard lab.
# generates a JSON list of categories if passed a parameter mode
# with the value of categories. Otherwise outputs a random question
# from the passed in category in XML.
$mode = $_GET["mode"];
$category = $_GET["category"];
$url = "../../cse154/services/flashcards/";
if($mode == "categories") {
outputJson($url);
} else {
outputXml($url, $category);
}
# outputs the list of available categories in JSON
function outputJson($url) {
$files = glob($url . "*");
$json = array("categories" => array());
foreach($files as $file) {
$count = count(glob($file."/*"));
$json["categories"][basename($file)] = $count;
}
header("Content-type: application/json");
print(json_encode($json));
}
# outputs a random question about the provided category in XML
function outputXml($url, $category) {
$files = glob($url . "$category/*");
$index = array_rand($files);
// this is a great place to use list!!
list($ques, $ans) = file($files[$index]);
$dom = new DOMDocument();
$card = $dom->createElement("card");
$dom->appendChild($card);
$question = $dom->createElement("question");
$question->appendChild($dom->createTextNode($ques));
$card->appendChild($question);
$answer = $dom->createElement("answer");
$answer->appendChild($dom->createTextNode($ans));
$card->appendChild($answer);
header("Content-type: text/xml");
print($dom->saveXML());
}
?>
/* javascript */
(function() {
var category = "computerscience";
var xml = null;
// sets up onclick handlers
window.onload = function() {
document.getElementById("viewAll").onclick = viewAll;
document.getElementById("next").onclick = next;
};
// sends an ajax request to the passed in address.
// calls the passed in function when the request returns.
function ajax($adress, $function) {
var request = new XMLHttpRequest();
request.onload = $function;
request.open("GET", $adress, true);
request.send();
}
// makes a request for all of the categories.
function viewAll() {
ajax("flashcards.php?mode=categories", displayAll);
}
// displays all categories in a list on the page.
function displayAll() {
$json = JSON.parse(this.responseText);
for($cat in $json.categories) {
var li = document.createElement("li");
li.innerHTML = $cat;
li.onclick = choose;
document.getElementById("categories").appendChild(li);
}
}
// sets a new category as the category all questions should come from.
function choose() {
category = this.innerHTML;
}
// displays the next question if it was last displaying an answer or nothing.
// displays the answer to the previous question otherwise.
function next() {
if(!xml) {
ajax("flashcards.php?category=" + category, displayNext);
} else {
document.getElementById("card").innerHTML = xml.querySelector("answer").textContent;
xml = null;
}
}
// displays the question that it recieved from the server.
function displayNext() {
xml = this.responseXML;
document.getElementById("card").innerHTML = xml.querySelector("question").textContent;
}
})();
I am passing a variable from an AJAX function to a PHP page. AJAX function is called on a button click & a value is passed as parameter. AJAX function passes this variable to a php page to_php_page.php from where a HTTP GET request is made to the server. This variable is passed as the parameter. We get many city datas as response. The corresponding response is stored in different arrays & is encoded as JSON & passed back to the AJAX function. All these datas are shown at once.
But, Instead of getting the response, I am getting an error.
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
AJAX Function
<script>
function get_data(n)
{
if(window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
else
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() //callback fn
{
if(xmlhttp.readyState==4 && xmlhttp.status==200)
{
var jsonStr = JSON.parse(xmlhttp.responseText);
var count_array=parseInt(jsonStr.count);
var la=jsonStr.la;
var ny=jsonStr.ny;
var sj=jsonStr.sj;
var lv=jsonStr.lv;
var ut=jsonStr.ut;
var dc=jsonStr.dc;
var miami=jsonStr.miami;
var columbus=jsonStr.columbus;
var kc=jsonStr.kc;
var ch=jsonStr.ch;
for (i = 0; i < count_array; i++)
{
(function()
{
alert(la);
alert(ny);
alert(sj);
alert(lv);
alert(ut);
alert(dc);
alert(miami);
alert(columbus);
alert(kc);
alert(ch);
})();
}
}
}
xmlhttp.open("GET","to_php_page.php?namee="+n,true);
xmlhttp.send();
}
</script>
to_php_page.php
<?php
$namee_value=$_GET["namee"];
// Above variable is passed as argument with the url to obtain the response.
$url="server_url?nam=".$namee_value;
$jsondata= httpGet($url);
$details_array = json_decode($jsondata, true);
$count=count($details_array['country']);
function httpGet($url)
{
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_HEADER, false);
$output=curl_exec($ch);
curl_close($ch);
return $output;
}
//for storing los angeles details
$la=array();
for($i=0;$i<$count;$i++)
{
$la[$i]= $details_array['country'][$i]['los_angeles'];
}
//for storing new york details
$ny=array();
for($i=0;$i<$count;$i++)
{
$ny[$i]= $details_array['country'][$i]['new_york'];
}
//for storing san jose details
$sj=array();
for($i=0;$i<$count;$i++)
{
$sj[$i]= $details_array['country'][$i]['san_jose'];
}
//for storing las vegas details
$lv=array();
for($i=0;$i<$count;$i++)
{
$lv[$i]= $details_array['country'][$i]['las_vegas'];
}
//for storing utah details
$ut=array();
for($i=0;$i<$count;$i++)
{
$ut[$i]= $details_array['country'][$i]['utah'];
}
//for storing washington details
$dc=array();
for($i=0;$i<$count;$i++)
{
$dc[$i]= $details_array['country'][$i]['washington_dc'];
}
//for storing miami details
$miami=array();
for($i=0;$i<$count;$i++)
{
$miami[$i]= $details_array['country'][$i]['miami'];
}
//for storing columbus details
$columbus=array();
for($i=0;$i<$count;$i++)
{
$columbus[$i]= $details_array['country'][$i]['columbus'];
}
//for storing kansas city details
$kc=array();
for($i=0;$i<$count;$i++)
{
$kc[$i]= $details_array['country'][$i]['kansas_city'];
}
//for storing chicago details
$ch=array();
for($i=0;$i<$count;$i++)
{
$ch[$i]= $details_array['country'][$i]['chicago'];
}
$what_the_array = array(
'count' => $count,
'la' => $la,
'ny' => $ny,
'sj'=> $sj,
'lv'=>$lv,
'ut'=>$ut,
'dc'=>$dc,
'miami'=>$miami,
'columbus'=>$columbus,
'kc'=>$kc,
'ch'=>$ch
);
echo json_encode($what_the_array);
?>
UPDATE:
JSON to be parsed:
{
"country":
[
{
"los_angeles": "value1",
"new_york": "value2",
"san_jose": "value3",
"las_vegas": "value4",
"utah": "value5",
"washington_dc": "value6",
"miami": "value7",
"columbus": "value8",
"kansas_city": "value9",
"chicago": "value10"
}
]
}
NB: Is there an alternative for the AJAX function I have used?? I mean, another AJAX function. I use this all time. I am looking for a much better AJAX function.
You may have two possible problem sources:
1) Content-Type. Specify content type and charset just before sending out JSON from PHP:
Header('Content-Type: application/json;charset=utf8');
(and ensure content is UTF8 encoded).
2) I have recently experienced your same problem. I'm 100% sure the JSON was correct (checked with jsonlint from data lifted off the wire with tcpdump) and the same code had worked up to the day before. The bug was not reproducible in Chrome. It also went unexplicably away after upgrading Firefox and clearing the cache, but it never presented itself on a still non-updated Firefox on another PC. In some cases I noticed that both Firefox and Chrome appear to request a JSON packet but process an earlier version from the cache, but was not able to reproduce the phenomenon in any predictable way. I do know though that to prevent it it is sufficient to add a non-repeating element to the query:
xmlhttp.open("GET","to_php_page.php?namee="+n + "&ts=" + Date.now(), true);
This effectively disables caching for that request, so for large JSON resources that change rarely, it isn't really a good thing to do.
Other possibilities
You ought to verify whether the cUrl request PHP side does return properly. You might have an error, possibly a cUrl warning of some kind issued by httpGet.
Try opening the URL directly in the browser. If you see something like
PHP Warning: curl_exec: ... { (JSON) }
well, that of course is not JSON and JSON.parse() will complain that the "P" in "PHP Warning" is indeed an unexpected character.
I am building a type of RSS Feed reader using Google's Feed API. After much trial and error, I have been able to instantiate a connection to a given RSS URL via PHP, and return the JSON object. The problem I run into is that I am attempting to validate multiple URLs from an array, but due to the asynchronous nature of AJAX, and loading time lag through the Google API, the results code fires off before the validation can complete. I have tried things like: forcing synchronicity, setTimeouts, .promise on objects that call the validation, ect but I'm getting no where. Any help at all would be immensely appreciated.
My Code:
PHP
$feed = $_POST['feed'];
$url = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=&q=" . $feed;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_REFERER, www.mywebsiteurl.com);
$body = curl_exec($ch);
curl_close($ch);
echo $body;
This snippet successfully creates a connection to the given Feed URL, and returns a JSON object containing the feed data. I am calling this external php script with the following AJAX call:
AJAX:
var conn = $.ajax({
url : "php/feedlog.php",
type : "post",
data : {feed: feed_a[i]}
});
conn.done(function (data){
var err = eval('(' + data + ')' ).responseStatus;
if (err==200){
console.log("Success");
} else if (err==400){
console.log("Failure with: " + err);
}
});
This code works flawlessly for a single connection attempt, but I need to linearly step through an array of feeds, testing a feed, waiting for the connection result, then proceeding to the next feed in the array, or breaking on a successful connection.
I have attempted to use an $.each statement for feed_a[], but the loop fires faster than the results can be returned. I think I need to operate a buffer, but I'm not sure how to implement it.
As always, if needed I can provide additional code, previous attempts, or greater clarification upon request. If needed I can host the code live at my website for demo purposes.
More direct question: How can I force a loop ($.each, for loop, or a recursive function) to wait for results from an AJAX call?
Also, in an attempt to make my questions better in the future, could someone explain why my question may have been marked down?
Edit: Thanks for the speedy response everyone! The following code appears to resolve my issue:
$.each(v_feed, function(_,url){
$.ajax("php/feedlog.php",{
type: "POST",
data: { feed: url }
}).done(function(data){
var err = eval('(' + data + ')' ).responseStatus;
if (err == 200){
console.log("success with: " + data);
} else if (err == 400){
console.log("fail with: " + data);
console.log("removing from valid array");
v_feed.splice(v_feed.length - _, 1);
}
//console.log(err);
}).fail(function(){
console.log("Fail");
}).complete(function(){
console.log(v_feed);
});
});
Loop through with $.each, creating the wrapper for each feed in the html before you send the ajax request, storing a reference to the wrapper. On done, populate the wrapper with the feed. This will allow you to retrieve them all at once while still adding them to the page in the correct order without having to wait for them all to complete.
$.each(feedArr, function(_,url){
var wrapper = $("<div>").appendTo(someel);
$.ajax("feed.php",{
type: "POST",
data: { url: url }
}).done(function(data){
// process data...
wrapper.append(generateFeedHTML(data));
}).fail(function(){
wrapper.remove();
});
});
Try that:
var arrayOfPromises = [];
//inside each/for loop, push request in array
arrayOfPromises.push($.ajax({
url : "php/feedlog.php",
type : "post",
data : {feed: feed_a[i]}
}));
And then outside of loop:
$.when.apply($, arrayOfPromises).done(function(data){
//all requests are done
});
I don't remember exactly which data will be passed to done(), check it.
Fire off the next call only on success:
var worked = {status:true},
conn = function(successLogic){
if(feed_a[i]) // I assume this is the loop end condition...
$.ajax({
url : "php/feedlog.php",
type : "post",
data : {feed: feed_a[i]},
success: function(data){
if(successLogic(data));
worked.status = worked.status && conn(successLogic); // Recursion instead of iteration!
},
error: function(err){
worked.status = false;
// your error code
}
});
else
return worked;
};
var completedRecusionPromise = conn(function(data){
var obj;
try{
obj = JSON.parse(data);
}catch(e){ console.log(e); }
return !!obj; // Assuming you just want valid JSON??
});