Performing an ajax call to a drinks api and I've nested a loop to pull the ingredients out and render them to the page. The nested loop consoles the ingredients correctly but when I use jquery to append the results to the page only the item in the last index is displayed. I know there are null values I was going to remove them with an if statement after I got them to show.
function displayDrinkData(drinkName) {
var queryURL = "https://thecocktaildb.com/api/json/v1/1/search.php?s=" + drinkName
$.ajax({
url: queryURL,
method: "GET"
}).then(function (response) {
console.log(response);
var results = response.drinks;
for (var i = 0; i < results.length; i++) {
console.log(results[i]);
var eachDrink = results[i];
var drinkDiv = $("<div>");
var drinkName = results[i].strDrink;
for (var k = 1; k < 16; k++) {
console.log(eachDrink['strIngredient' + k]);
var ingList = $("<ul>").text("Ingredients: " + eachDrink['strIngredient' + k])
}
var pOne = $("<p>").text("Drink name: " + drinkName);
var drinkInstructions = results[i].strInstructions;
var pTwo = $("<p>").text("Instructions: " + drinkInstructions);
var drinkImage = $("<img>");
drinkImage.attr("src", results[i].strDrinkThumb);
drinkDiv.append(pOne);
drinkDiv.append(ingList);
drinkDiv.append(pTwo);
drinkDiv.append(drinkImage);
$("#drinks-view").append(drinkDiv);
}
})
}
Because var ingList is inside loop, not appending, but creating a new one every time.
var ingList = $("<ul>");
for (var k = 1; k < 16; k++) {
console.log(eachDrink['strIngredient' + k]);
ingList.append($('<li>').text("Ingredients: " + eachDrink['strIngredient' + k]));
}
Declare variable outside loop, and append <li> for each element.
I'm writing a google docs apps script in making a google docs add-on. When the user clicks a button in the sidebar, an apps script function is called named executeSpellChecking. This apps script function makes a remote POST call after getting the document's text.
total time = time that takes from when user clicks the button, until the .withSuccessHandler(, that means until executeSpellChecking returns = 2000 ms
function time = time that takes for the executeSpellChecking call to complete from its start to its end = 1400 ms
t3 = time that takes for the remote POST call to be completed = 800ms
t4 = time that takes for the same remote POST call to complete in a VB.NET app = 200ms
Problems:
Why total time to complete is bigger than total function time by a staggering 600ms, what else happens there? shouldn't they be equal? How can I improve it?
Why t3 is bigger than t4 ? Shouldn't they be equal? Is there something wrong with POST requests when happening from .gs? How can I improve it ?
the code is (sidebar.html):
function runSpellChecking() {
gb_IsSpellcheckingRunning = true;
//gb_isAutoCorrecting = false;
gi_CorrectionCurrWordIndex = -1;
$("#btnStartCorr").attr("disabled", true);
$("#divMistakes").html("");
this.disabled = true;
//$('#error').remove();
var origin = $('input[name=origin]:checked').val();
var dest = $('input[name=dest]:checked').val();
var savePrefs = $('#save-prefs').is(':checked');
//var t1 = new Date().getTime();
console.time("total time");
google.script.run
.withSuccessHandler(
function(textAndTranslation, element) {
if (gb_IsSpellCheckingEnabled) {
console.timeEnd("total time");
//var t2 = new Date().getTime();
go_TextAndTranslation = JSON.parse(JSON.stringify(textAndTranslation));
var pagewords = textAndTranslation.pagewords;
var spellchecked = textAndTranslation.spellchecked;
//alert("total time to complete:" + (t2-t1) + "###" + go_TextAndTranslation.time);
//irrelevant code follows below...
}
})
.withFailureHandler(
function(msg, element) {
showError(msg, $('#button-bar'));
element.disabled = false;
})
.withUserObject(this)
.executeSpellChecking(origin, dest, savePrefs);
}
and the called function code is (spellcheck.gs):
function executeSpellChecking(origin, dest, savePrefs) {
//var t1 = new Date().getTime();
console.time("function time");
var body = DocumentApp.getActiveDocument().getBody();
var alltext = body.getText();
var lastchar = alltext.slice(-1);
if (lastchar != " " && lastchar != "\n") {
body.editAsText().insertText(alltext.length, "\n");
alltext = body.getText();
}
var arr_alltext = alltext.split(/[\s\n]/);
var pagewords = new Object;
var pagewordsOrig = new Object;
var pagewordsOrigOffset = new Object;
var offset = 0;
var curWord = "";
var cnt = 0;
for (var i = 0; i < arr_alltext.length; i++) {
curWord = arr_alltext[i];
if (StringHasSimeioStiksis(curWord)) {
curWord = replaceSimeiaStiksis(curWord);
var arr3 = curWord.split(" ");
for (var k = 0; k < arr3.length; k++) {
curWord = arr3[k];
pagewords["" + (cnt+1).toString()] = curWord.replace(/[`~##$%^&*()_|+\-="<>\{\}\[\]\\\/]/gi, '');
pagewordsOrig["" + (cnt+1).toString()] = curWord;
pagewordsOrigOffset["" + (cnt+1).toString()] = offset;
offset += curWord.length;
cnt++;
}
offset++;
} else {
pagewords["" + (cnt+1).toString()] = curWord.replace(/[`~##$%^&*()_|+\-="<>\{\}\[\]\\\/\n]/gi, '');
pagewordsOrig["" + (cnt+1).toString()] = curWord;
pagewordsOrigOffset["" + (cnt+1).toString()] = offset;
offset += curWord.length + 1;
cnt++;
}
}
var respTString = "";
var url = 'https://www.example.org/spellchecker.php';
var data = {
"Text" : JSON.stringify(pagewords),
"idOffset" : "0",
"lexID" : "8",
"userEmail" : "test#example.org"
};
var payload = JSON.stringify(data);
var options = {
"method" : "POST",
"contentType" : "application/json",
"payload" : payload
};
//var t11 = new Date().getTime();
console.time("POST time");
var response = UrlFetchApp.fetch(url, options);
console.timeEnd("POST time");
//var t22 = new Date().getTime();
var resp = response.getContentText();
respTString = resp;
var spellchecked = JSON.parse(respTString);
var style = {};
for (var k in pagewords){
if (pagewords.hasOwnProperty(k)) {
if (spellchecked.hasOwnProperty(k)) {
if (spellchecked[k].substr(0, 1) == "1") {
style[DocumentApp.Attribute.FOREGROUND_COLOR] = "#000000";
}
if (spellchecked[k].substr(0, 1) == "0") {
style[DocumentApp.Attribute.FOREGROUND_COLOR] = "#FF0000";
}
if (spellchecked[k].substr(0, 1) == "4") {
style[DocumentApp.Attribute.FOREGROUND_COLOR] = "#0000FF";
}
if (pagewordsOrigOffset[k] < alltext.length) {
body.editAsText().setAttributes(pagewordsOrigOffset[k], pagewordsOrigOffset[k] + pagewordsOrig[k].length, style);
}
}
}
}
//var t2 = new Date().getTime();
console.timeEnd("function time")
return {
"pagewords" : pagewords,
"pagewordsOrig" : pagewordsOrig,
"pagewordsOrigOffset" : pagewordsOrigOffset,
"spellchecked" : spellchecked
}
}
Thank you in advance for any help.
EDIT: I updated the code to use console.time according to the suggestion, the results are:
total time: 2048.001953125 ms
Jun 21, 2021, 3:01:40 PM Debug POST time: 809ms
Jun 21, 2021, 3:01:41 PM Debug function time: 1408ms
So the problem is not how time is measured. function time is 1400ms, while the time it takes to return is 2000ms, a difference of 600ms and the POST time is a staggering 800ms, instead of 200ms it takes in VB.net to make the exact same POST call.
Use console.time() and console.timeEnd():
https://developers.google.com/apps-script/reference/base/console
I modified the code for you. console.timeEnd() outputs the time duration in the console automatically, so I removed the alert for you that showed the time difference.
You might want the strings that I used as the parameter as some sort of constant variable, so there are no magic strings used twice. I hope this is of use to you.
function runSpellChecking() {
gb_IsSpellcheckingRunning = true;
//gb_isAutoCorrecting = false;
gi_CorrectionCurrWordIndex = -1;
$("#btnStartCorr").attr("disabled", true);
$("#divMistakes").html("");
this.disabled = true;
//$('#error').remove();
var origin = $('input[name=origin]:checked').val();
var dest = $('input[name=dest]:checked').val();
var savePrefs = $('#save-prefs').is(':checked');
console.time("total time");
google.script.run
.withSuccessHandler(
function(textAndTranslation, element) {
if (gb_IsSpellCheckingEnabled) {
console.timeEnd("total time");
go_TextAndTranslation = JSON.parse(JSON.stringify(textAndTranslation));
var pagewords = textAndTranslation.pagewords;
var spellchecked = textAndTranslation.spellchecked;
//irrelevant code follows below...
}
})
.withFailureHandler(
function(msg, element) {
showError(msg, $('#button-bar'));
element.disabled = false;
})
.withUserObject(this)
.executeSpellChecking(origin, dest, savePrefs);
}
function executeSpellChecking(origin, dest, savePrefs) {
console.time("function time");
var body = DocumentApp.getActiveDocument().getBody();
var alltext = body.getText();
var lastchar = alltext.slice(-1);
if (lastchar != " " && lastchar != "\n") {
body.editAsText().insertText(alltext.length, "\n");
alltext = body.getText();
}
var arr_alltext = alltext.split(/[\s\n]/);
var pagewords = new Object;
var pagewordsOrig = new Object;
var pagewordsOrigOffset = new Object;
var offset = 0;
var curWord = "";
var cnt = 0;
for (var i = 0; i < arr_alltext.length; i++) {
curWord = arr_alltext[i];
if (StringHasSimeioStiksis(curWord)) {
curWord = replaceSimeiaStiksis(curWord);
var arr3 = curWord.split(" ");
for (var k = 0; k < arr3.length; k++) {
curWord = arr3[k];
pagewords["" + (cnt+1).toString()] = curWord.replace(/[`~##$%^&*()_|+\-="<>\{\}\[\]\\\/]/gi, '');
pagewordsOrig["" + (cnt+1).toString()] = curWord;
pagewordsOrigOffset["" + (cnt+1).toString()] = offset;
offset += curWord.length;
cnt++;
}
offset++;
} else {
pagewords["" + (cnt+1).toString()] = curWord.replace(/[`~##$%^&*()_|+\-="<>\{\}\[\]\\\/\n]/gi, '');
pagewordsOrig["" + (cnt+1).toString()] = curWord;
pagewordsOrigOffset["" + (cnt+1).toString()] = offset;
offset += curWord.length + 1;
cnt++;
}
}
var respTString = "";
var url = 'https://www.example.org/spellchecker.php';
var data = {
"Text" : JSON.stringify(pagewords),
"idOffset" : "0",
"lexID" : "8",
"userEmail" : "test#example.org"
};
var payload = JSON.stringify(data);
var options = {
"method" : "POST",
"contentType" : "application/json",
"payload" : payload
};
console.time("POST time");
var response = UrlFetchApp.fetch(url, options);
console.timeEnd("POST time");
var resp = response.getContentText();
respTString = resp;
var spellchecked = JSON.parse(respTString);
var style = {};
for (var k in pagewords){
if (pagewords.hasOwnProperty(k)) {
if (spellchecked.hasOwnProperty(k)) {
if (spellchecked[k].substr(0, 1) == "1") {
style[DocumentApp.Attribute.FOREGROUND_COLOR] = "#000000";
}
if (spellchecked[k].substr(0, 1) == "0") {
style[DocumentApp.Attribute.FOREGROUND_COLOR] = "#FF0000";
}
if (spellchecked[k].substr(0, 1) == "4") {
style[DocumentApp.Attribute.FOREGROUND_COLOR] = "#0000FF";
}
if (pagewordsOrigOffset[k] < alltext.length) {
body.editAsText().setAttributes(pagewordsOrigOffset[k], pagewordsOrigOffset[k] + pagewordsOrig[k].length, style);
}
}
}
}
console.timeEnd("function time");
return {
"pagewords" : pagewords,
"pagewordsOrig" : pagewordsOrig,
"pagewordsOrigOffset" : pagewordsOrigOffset,
"spellchecked" : spellchecked
}
}
I have a function which makes an AJAX call and depending on the answer, sets the colour of an input. The function core itself works fine. However, when it comes to changing the colour of the input, it is not working.
function Nueva_Red() {
var e1 = document.getElementById("rrss_tipo");
var e2 = document.getElementById("rrss_usuario");
var e3 = document.getElementById("redes");
var e4 = document.getElementById("alta_nueva_red");
var id_red = e1.options[e1.selectedIndex].value;
var red = e1.options[e1.selectedIndex].text;
var usuario = e2.value;
e2.style.backgroundColor = "none";
e2.style.borderColor = "black";
if ((id_red > 0) && (usuario != "")) {
var datastr = 'seccion=rrss_check&dato=' + id_red + "|" + usuario;
$.ajax({
type: 'GET',
url: 'validacion.php',
data: datastr,
success: function(html) {
if (html == 1) {
document.getElementById("nuevas_rrss").style.visibility = "visible";
document.getElementById("nuevas_rrss").style.display = "inline-block";
var opcion = document.createElement("option");
opcion.value = id_red + "-" + usuario;
opcion.innerHTML = red + " -> " + usuario;
e3.appendChild(opcion);
e1.value = 0;
e2.value = "";
e2.title = "";
e2.style.backgroundColor = "none";
e2.style.borderColor = "black";
} else {
e2.title = html;
e2.style.backgroundColor = error_error;
e2.style.borderColor = error_error;
}
},
error: function(html) {
e2.style.borderColor = error_app;
e2.style.backgroundColor = error_app;
}
});
}
}
Thank you!
I have created a related post javascript for blogger.com based blogs. The related post plugins loops though the label attached to the current post and displays other posts with the same label.
You can find that in action # http://www.techquark.com/2017/07/infocus-turbo-5-affordable-powerful.html
The issue is I want to skip the current post to be shown in the related post, but unable to achieve the same.
PFB the javascript code :
$(".related-ready").each(function() {
var b = $(this).text();
$.ajax({
url: "/feeds/posts/default/-/" + b + "?alt=json-in-script&max-results=3",
type: 'get',
dataType: "jsonp",
success: function(e) {
var u = "";
var h = '<div class="related">';
for (var i = 0; i < e.feed.entry.length; i++) {
for (var j = 0; j < e.feed.entry[i].link.length; j++) {
if (e.feed.entry[i].link[j].rel == "alternate") {
u = e.feed.entry[i].link[j].href;
break
}
}
var g = e.feed.entry[i].title.$t;
var c = e.feed.entry[i].content.$t;
var $c = $('<div>').html(c);
if (c.indexOf("//www.youtube.com/embed/") > -1) {
var p = e.feed.entry[i].media$thumbnail.url;
var k = p
} else if (c.indexOf("<img") > -1) {
var q = $c.find('img:first').attr('src');
var k = q
} else {
var k = NO_IMAGE
}
h += '<li><div class="related-thumb"><a class="related-img" href="' + u + '" style="background:url(' + k + ') no-repeat center center;background-size: cover"/></div><h3 class="related-title">' + g + '</h3></li>'
}
h += '</div><div class="clear"/>';
$(".related-ready").html(h);
$('.related-img').each(function() {
$(this).attr('style', function(i, src) {
return src.replace('/default.jpg', '/hqdefault.jpg')
}).attr('style', function(i, src) {
return src.replace('s72-c', 's1600')
})
})
}
})
});
TIA !
You will need to check whether the current Post's ID matches with the ID of the post in feed and then skip that post, the code will look like -
....
for (var i = 0; i < e.feed.entry.length; i++) {
if(e.feed.entry[i].id.$t.split("post-")[1] === "<data:post.id/>"){
break;
}
for (var j = 0; j < e.feed.entry[i].link.length; j++) {
....
Javascript:
function add_content(count)
{
var result = {};
var row = new Array();
for (i = 0; i < count; i++)
{
result['img_src'] = $("#img_" + i).attr('src');
result['desc'] = $("#desc_" + i).val();
row.push(result);
}
$.ajax({
url: "ajax-functions.php",
data: {json_data: JSON.stringify(row)},
type: 'post',
success: function (output) {
alert(output);
}
})
}
Php:
$img_desc = json_decode($_POST['json_data'],TRUE);
$count = count($img_desc);
echo 'count:'.$count;
print_r($img_desc);
I want to send json to from JS to PHP. This above code works well, but it send the last data of the for loop is set in all the objects.
How to fix it? Is this right way?
Thanks.
Push a new object on each round of the loop into to the array
for (var i = 0; i < count; i++) {
row.push({
"img_src": $("#img_" + i).attr('src'),
"desc": $("#desc_" + i).val()
});
}
fiddle
Move result declaration inside for:
var row = new Array();
for (i = 0; i < count; i++)
{
var result = {};
result['img_src'] = $("#img_" + i).attr('src');
result['desc'] = $("#desc_" + i).val();
row.push(result);
}
or it can be done more elegantly:
var row = new Array();
var result;
for (i = 0; i < 10; i++)
{
result = row[ row.push({}) - 1 ];
result['img_src'] = $("#img_" + i).attr('src');
result['desc'] = $("#desc_" + i).val();
}
You can make the keys of result array also dynamic
Since you are not making it dynmamic, its getting over ridden in the next loop
EDIT:
for (i = 0; i < count; i++)
{
var result = {};
result['img_src'] = $("#img_" + i).attr('src');
result['desc'] = $("#desc_" + i).val();
row.push(result);
}