JSON returns urls twice - javascript

I have an html table on a page with raws that have 'urls', I'm trying to fetch one url at a time from a random row, however my code returns url as http://www.test.com/products/product-namehttp://www.test.com/products/product-name.json, as you can see it returns url twice, one without json and other with json data, hence I'm getting 404.
I just need the .json URL, not the first part.
How do I get rid of the first url which is not json?
Here's the code.
$(document).ready(function() {
$(document).on('click', '#closepopup', function() {
$("#popup").removeClass('popupslidein')
});
var tablelink = "https://test.com/pages/product-listing-for-popups.json"; //products url for json data
$.getJSON(tablelink, function(data) {
var table = data.page.body_html;
$('#popuptable').append(table);
startthepopups()
});
var suburbink = "https://test.com/pages/product-listing-suburbs-for-popups"; //suburb names in table rows
$.getJSON(suburbink, function(data) {
var suburb = data.page.body_html;
$('#popupsuburb').append(suburb)
});
var namelink = "https://test.com/pages/product-listing-names-for-popups"; //names in table rows
$.getJSON(namelink, function(data) {
var name = data.page.body_html;
$('#popupname').append(name)
});
function startthepopups() {
var popupstay = 10000;
var popuptrigger = 100000;
function triggerpopup() {
var getrandomtd = Math.floor((Math.random() * $('#popuptable tr').length) + 1);
var link = $('#popuptable tr:nth-child(' + getrandomtd + ')').text();
console.log(link);
var productname = '';
var getrandomsuburbtd = Math.floor((Math.random() * $('#popupsuburb tr').length) + 1);
var suburblink = $('#popupsuburb tr:nth-child(' + getrandomsuburbtd + ')').text();
var getrandomnametd = Math.floor((Math.random() * $('#popupname tr').length) + 1);
var randomname = $('#popupname tr:nth-child(' + getrandomnametd + ')').text();
$.getJSON(link + '.json', function(data) {
productname = data.product.title;
imagelink = data.product.images[0].src;
if (!$("#popup").hasClass("popupslidein")) {
$('#popupsomeone span.name').empty().append(randomname);
$('#popupsomeone span.location').empty().append(suburblink);
$('#popupimage').css('background-image', 'url(' + imagelink.split('.jpg')[0] + '_small.jpg)');
$('#popupproduct a').attr('href', link).empty().append(productname);
$("#popupagotext").empty().append(Math.round(Math.random() * 15 + 10));
$("#popup").addClass('popupslidein');
setTimeout(function() {
$("#popup").removeClass('popupslidein')
}, popupstay);
}
});
}(function loop() {
var random = Math.round(Math.random() * 10) * 100000 + popuptrigger;
setTimeout(function() {
triggerpopup();
loop()
}, 60000)
}());
}
});

$.getJSON() has a tendency to append your current url to the path you pass it if it thinks it's relative. To make this work, you could try to use $.getJSON() like so. Keep in mind, the protocol used will be the current page this code lives on.
$.getJSON('//test.com/pages/product-listing-for-popups.json')
I also noticed that nowhere in your code do you have a url for http://www.test.com/products/product-name.json, are you sure you're sharing the correct snippet of code?
Working Demo
The following two ways of using $.getJSON() with a fully qualified url work perfectly fine:
$(document).ready(function() {
var url = "https://jsonplaceholder.typicode.com/todos/1";
// Example 1
$.getJSON(url)
.done(function( data ) {
console.log(data);
});
// Example 2
$.getJSON(url, function(data) {
console.log(data)
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Related

How can I wait until all my images are loaded before adding them to html?

I am trying to get multiple images from an ajax source and load the on the page when they have all finished loading. The issue I was having that has caused me to try to find a solution was that some of the images weren't loading even though those images existed on the server.
I have tried to add code that now adds the image to an array
design_images.push({cid:designImg});
... and then when all the images have loaded will add that to the page, but I can't get that to work.
var counter = 0;
$(design_images).load(function() { // many or just one image(w) inside body or any other container
counter += 1;
}).each(function(key, value) {
this.complete && $(this).load();
console.log(value);
});
Nothing is outputted from the .each
This is the output of the array design_images
The value of design_images.length is 0 though.
Here is the complete function:
function matte_design_change_design_type(element)
{
var element_value = null;
var mattes_selected_type = get_mattes_selected_type();
matte_design_widths[mattes_selected_type] = [];
var mattes_selected_design = get_mattes_selected_design();
var count_matte_designs = 0;
var found = false;
$(document).ready(function()
{
$.ajax(
{
type: "GET",
url: SITE_URL + "/system/components/xml/" + mattes_selected_type,
dataType: 'xml',
success: function(xml)
{
var output = [];
var design_images = [];
$('component', xml).each(function(i, el)
{
matte_design_widths[mattes_selected_type][i] = 0;
count_matte_designs++;
var thumb = $("thumb", this).text(),
cid = $("cid", this).first().text(),
name = $("name", this).first().text().replace("Collage - ", ""),
alt = name,
description = $("description", this).first().text(),
if (parseInt(cid, 10) === mattes_selected_design)
{
found = true;
$("#matte_design_name").html(name);
$("#matte_design_description").html(description);
}
var designImg = new Image();
designImg.id = 'cid_' + cid;
designImg.alt = alt;
designImg.onclick = function() {
matte_design_change(cid, mattes_selected_type);
};
designImg.onload = function() {
output.push('<span class="matte_design_image_name" id="design_' + cid + '"><img id="cid_' + cid + '" />');
output.push('<br /><span class="matte_design_name" id="matte_design_name_' + mattes_selected_type + '_' + i + '">' + name + '</span></span>');
matte_design_increase_width(mattes_selected_type, this.width, i);
$('#matte_designs_strip_wrapper').html(output.join(''));
};
designImg.src = 'https://example.com/system/components/compimg/' + thumb + '/flashthumb';
});
var counter = 0;
var size = $('img').length;
$(design_images).load(function() {
counter += 1;
}).each(function(key, value) {
this.complete && $(this).load();
console.log(value);
});
}
});
});
}
I have tried waitForImages and imagesLoaded but I couldn't get them to work for me, but I'm not opposed to using either one.
Hide all images by default using CSS
img{
display: none;
}
Use Jquery to check if all loaded, then display images
JQuery
$(window).load(function(){
$('img').fadeIn(800); //or $('img').show('slow');
});

Fetching data with AJAX call, click handler causing issues displaying info

Where I'm At
I'm making a form for an online silent auction. People click a button, choose one of six fixed amounts $10, $25, $50, $100, $250, $500 and that amount gets added to the last bid, giving us total amount of their new bid.
Problem
It takes an extraordinarily long time (4-5 seconds after the button is clicked) to replace the tk-amount placeholder using.html to .current__amount and .new__amount and display these two pieces of data grabbed from a Google Spreadsheet using an AJAX call to the SheetsU API.
I have a feeling it's because of how much stuff is being done everytime a button is clicked. Is there a better way to approach this?
scripts.js
// Bid Options
$(".button__form").on('click', function(){
var btnSelected = $(this).hasClass("is-selected");
var sectionOneCompleted = $(".check--one").hasClass("is-completed");
if (btnSelected) {
$(this).removeClass("is-selected");
$(".check--one").css("color", "#ccc");
} else {
$(".button__form").removeClass("is-selected");
$(this).addClass("is-selected");
$(".check--one").css("color", "#ffdc00");
}
});
$(".button__form").on("click", function() {
var lastbtnClicked = ($(this).attr("class"));
// Bid Options
var buttonOne = $(this).hasClass("button__one");
var buttonTwo = $(this).hasClass("button__two");
var buttonThree = $(this).hasClass("button__three");
var buttonFour = $(this).hasClass("button__four");
var buttonFive = $(this).hasClass("button__six");
var buttonSix = $(this).hasClass("button__six");
// Bid Values
var buttonOneValue = 10;
var buttonTwoValue = 25;
var buttonThreeValue = 50;
var buttonFourValue = 100;
var buttonFiveValue = 250;
var buttonSixValue = 500;
/*-------------------------------------
API: SHEETSU
--------------------------------------*/
$.ajax({
url: "https://sheetsu.com/apis/4a8eceba",
method: "GET",
dataType: "json"
}).then(function(spreadsheet) {
// Get and print data
var currentBid = parseInt(spreadsheet.result.pop().Bids);
console.log(currentBid);
var phoneNumber = "1" + spreadsheet.result.pop()["Phone Number"];
var printBid = $(".current__amount").html("$" + currentBid);
console.log(printBid);
if (buttonOne) {
$(".new__amount").html("$" + (currentBid + buttonOneValue));
} else if (buttonTwo) {
$(".new__amount").html("$" + (currentBid + buttonTwoValue));
} else if (buttonThree) {
$(".new__amount").html("$" + (currentBid + buttonThreeValue));
} else if (buttonFour) {
$(".new__amount").html("$" + (currentBid + buttonFourValue));
} else if (buttonFive) {
$(".new__amount").html("$" + (currentBid + buttonFiveValue));
} else if (buttonSix) {
$(".new__amount").html("$" + (currentBid + buttonSixValue));
}
});
});
Are you sure your "performance issues" arn't actually caused by your http request taking 4-5 seconds to complete? To check open your browsers console and click on the network tab. Then press your button. You should see a request send out and how long it takes to complete.
Lets go one by one
Take these out of callback, no need to reinitialize for every click.
// Bid Values
var buttonOneValue = 10;
var buttonTwoValue = 25;
var buttonThreeValue = 50;
var buttonFourValue = 100;
var buttonFiveValue = 250;
var buttonSixValue = 500;
Reduce below
$(".button__form").on('click', function(){
var btnSelected = $(this).hasClass("is-selected");
var sectionOneCompleted = $(".check--one").hasClass("is-completed");
if (btnSelected) {
$(this).removeClass("is-selected");
$(".check--one").css("color", "#ccc");
} else {
$(".button__form").removeClass("is-selected");
$(this).addClass("is-selected");
$(".check--one").css("color", "#ffdc00");
}
});
to this
$(".button__form").on('click', function(){
$(this).toggleClass("is-selected");
$(".check--one").toggleClass("is-completed");
});
//And adjust the color of .check--one in css
And use the class property efficiently
if (buttonOne) {
$(".new__amount").html("$" + (currentBid + buttonOneValue));
} else if (buttonTwo) {
$(".new__amount").html("$" + (currentBid + buttonTwoValue));
} else if (buttonThree) {
$(".new__amount").html("$" + (currentBid + buttonThreeValue));
} else if (buttonFour) {
$(".new__amount").html("$" + (currentBid + buttonFourValue));
} else if (buttonFive) {
$(".new__amount").html("$" + (currentBid + buttonFiveValue));
} else if (buttonSix) {
$(".new__amount").html("$" + (currentBid + buttonSixValue));
}
to something like this in for loop
$(".new__amount."+buttons[i].class).html("$" + (currentBid + buttons[i].value));
var buttons = [{class:"buttonSix", value:123},....]
So at last your code could look like this.
// Bid Options
var buttons = [{class:"buttonOne", value:12},....{class:"buttonSix", value:123}]
$(".button__form").on('click', function(){
$(this).toggleClass("is-selected");
$(".check--one").toggleClass("is-completed");
//And adjust the color of .check--one in css
var lastbtnClicked = ($(this).attr("class"));
/*-------------------------------------
API: SHEETSU
--------------------------------------*/
$.ajax({
url: "https://sheetsu.com/apis/4a8eceba",
method: "GET",
dataType: "json"
}).then(function(spreadsheet) {
// Get and print data
var currentBid = parseInt(spreadsheet.result.pop().Bids);
console.log(currentBid);
var phoneNumber = "1" + spreadsheet.result.pop()["Phone Number"];
var printBid = $(".current__amount").html("$" + currentBid);
console.log(printBid);
var $btnForm = $(".button__form")
for(){
if($btnForm.hasClass(buttons[i].class)){
$(".new__amount.").html("$" + (currentBid + buttons[i].value));
}
}
});
});

Loading functions once page has loaded

I cant figure out where I have gone wrong. I am trying to have it so that a random index is selected then from that index the corresponding item in the array is chosen and displayed. However, at the moment nothing is being displayed. I think this is because the functions are not loading after the page has loaded and I'm not sure how to do this correctly. If you see any other errors in my current code please feel free to leave some feedback. Thanks :)
JS
<script type="text/javascript">
$(document).ready(function() {
function getRandomVideo() {
//Arrays for videos, titles, images, and searches
var videos = ['https://www.youtube.com/embed/kiTO7c_qeZs', 'https://www.youtube.com/embed/z4Hfv00eqoI', 'https://www.youtube.com/embed/7cdZYQB5ONE', 'https://www.youtube.com/embed/i1gE3nyQnKg', ];
var titles = ['Beethoven - Music, Love and Wine', 'Mozart String Serenade No.13', 'Beethoven Sonata No. 31 in A Flat Major', "Debussy - Children's Corner", ];
var images = ["url('Assets/beethoven.jpg')", "url('Assets/mozart.jpg')", "url('Assets/beethoven.jpg')", "url('Assets/debussy.jpg')", ]
var searches = ['beethoven+biography&s=0', 'wolfgang+mozart&s=0', 'beethoven+biography&s=0', 'Claude+Debussy&s=1', ];
//Gets a random index then uses said index to select an option in the array
var rand = Math.floor(Math.random() * videos.length);
var video = videos[rand];
var title = titles[rand];
var image = images[rand];
var search = searches[rand];
//replaces parts of html with selected option from array
document.getElementById("songTitle").innerHTML = title;
document.getElementById("img").style.backgroundImage = image;
document.getElementById("randomVideo").src = video;
return search
}
var apiKey = "jja10ssv4950uh65";
//I want to do this function and the one abovevwhen the document is loaded
$(document).onload(function() {
var searchTerm = getRandomVideo();
var url = "http://api.trove.nla.gov.au/result?key=" + apiKey + "&encoding=json&zone=newspaper&sortby=relevance&q=" + searchTerm + "&s=0&n=5&include=articletext,pdf&encoding=json&callback=?";
console.log(url);
$.getJSON(url, function(data) {
$('#output').empty();
$.each(data.response.zone[0].records.article, function(index, value) {
$("#output").append("<p>" + value.articleText + "</p>");
});
});
});
});
</script>
When you call the function try like this...E.g:
<button onclick="$(function(){getRandomVideo()});">Test</button>
And let
<script type="text/javascript">
function getRandomVideo() {
// Your codes..
}
</script>
Remove the onload part from from your jquery code and it will work.
$(document).ready(function() {
function getRandomVideo() {
//Arrays for videos, titles, images, and searches
var videos = ['https://www.youtube.com/embed/kiTO7c_qeZs', 'https://www.youtube.com/embed/z4Hfv00eqoI', 'https://www.youtube.com/embed/7cdZYQB5ONE', 'https://www.youtube.com/embed/i1gE3nyQnKg', ];
var titles = ['Beethoven - Music, Love and Wine', 'Mozart String Serenade No.13', 'Beethoven Sonata No. 31 in A Flat Major', "Debussy - Children's Corner", ];
var images = ["url('Assets/beethoven.jpg')", "url('Assets/mozart.jpg')", "url('Assets/beethoven.jpg')", "url('Assets/debussy.jpg')", ]
var searches = ['beethoven+biography&s=0', 'wolfgang+mozart&s=0', 'beethoven+biography&s=0', 'Claude+Debussy&s=1', ];
//Gets a random index then uses said index to select an option in the array
var rand = Math.floor(Math.random() * videos.length);
var video = videos[rand];
var title = titles[rand];
alert(title);
var image = images[rand];
var search = searches[rand];
//replaces parts of html with selected option from array
document.getElementById("songTitle").innerHTML = title;
document.getElementById("img").style.backgroundImage = image;
document.getElementById("randomVideo").src = video;
return search
}
var apiKey = "jja10ssv4950uh65";
//I want to do this function and the one abovevwhen the document is loaded
var searchTerm = getRandomVideo();
var url = "http://api.trove.nla.gov.au/result?key=" + apiKey + "&encoding=json&zone=newspaper&sortby=relevance&q=" + searchTerm + "&s=0&n=5&include=articletext,pdf&encoding=json&callback=?";
console.log(url);
$.getJSON(url, function(data) {
$('#output').empty();
$.each(data.response.zone[0].records.article, function(index, value) {
$("#output").append("<p>" + value.articleText + "</p>");
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="songTitle"></div>
.onload is not a jQuery method . At .ready() at beginning of js document should be loaded at call to $.getJSON()
$(document).ready(function() {
// do stuff
var apiKey = "jja10ssv4950uh65";
var searchTerm = getRandomVideo();
var url = "http://api.trove.nla.gov.au/result?key=" + apiKey + "&encoding=json&zone=newspaper&sortby=relevance&q=" + searchTerm + "&s=0&n=5&include=articletext,pdf&encoding=json&callback=?";
console.log(url);
$.getJSON(url, function(data) {
$('#output').empty();
$.each(data.response.zone[0].records.article, function(index, value) {
$("#output").append("<p>" + value.articleText + "</p>");
});
});
})

Multiple set interval script

I have a code to put two cameras on my site:
$(document).ready(function(){
var m;
var index;
var IP;
var port;
var name;
var user;
var password;
var image_old;
var image_new;
var cameraFeed;
var topImage;
var urls = [];
$.ajax({
type: "GET",
url: "json.htm?type=cameras",
dataType: "JSON",
async : false,
success: function(data) {
for(m=0; m<=1; m++){
index = data.result[m].idx;
IP = data.result[m].Address;
port = data.result[m].Port;
name = data.result[m].Name;
user = data.result[m].Username;
password = data.result[m].Password;
image_old = data.result[m].ImageURL;
image_new = image_old.replace("#USERNAME", user).replace("#PASSWORD", password);
cameraFeed = "http://" + IP + ":" + port + "/" + image_new;
alert(cameraFeed + m);
urls.push(cameraFeed);
}
setInterval(function() {
var d = Date.now();
$.each(urls, function(i, url) {
$('#topImage' + i).attr('src', url + "&timestamp=" + d);
});
}, 100);
},
error: function(data) {
alert("Error")
}
});
});
And html code:
<img id="topImage0" width="640px">
<img id="topImage1" width="640px">
I can not create a script to make setinterval work for both imgs. It works only for one of them. Any suggestions how to make it works ?
Set interval works only for one img.
To give you an idea how to structure your application code:
Get the data from the server
Create the URLs from data
Update each image every X milliseconds with those URLs
In code:
$.ajax({...}).done(function(data) { // get data from server
// create URLs
var urls = [];
for (var m = 0; m < 2; m++) { // why not iterate over data.results?
var cameraFeed;
// build cameraFeed ...
urls.push(cameraFeed);
}
// Update images
setInterval(function() {
var d = Date.now();
$.each(urls, function(i, url) {
$('#topImage' + i).attr('src', url + "&timestamp=" + d);
});
}, 100);
});
Of course this can still be approved, but that should point you into the right direction. Note in particular that it is unnecessary to have a setInterval for each image. Just let a single interval update all images.
Especially the for loop can be approved upon. I don't know how many results data.results has and if you only want to get the first two, but this is an excellent use case for Array#map:
var urls = data.results.map(function(result) {
// ...
return cameraFeed;
});

How to stop code from trying to load more posts from DB when all posts are loaded

My code loads new data when user reaches bottom of the page successfully but still when all posts from DB are loaded code tries to get more posts which results the page to stuck for several seconds. What i need is mechanism to detect when the last post has been loaded from DB and prevent code from executing.
function yHandler(){
var id=$(".output:last").attr("id");
var split = id.split("output");
var newid=split[1];
var awrap = document.getElementById('awrap');
var contentHeight = awrap.offsetHeight;
var yOffset = window.pageYOffset;
var y = yOffset + window.innerHeight;
var sesid=$("#sesid").val();
if(y >= contentHeight){
// Ajax call to get more dynamic data goes here
$.ajax({
url:"load.php",
type:"POST",
data:'did=' + did + '&newid=' + newid + '&id=' + id + "&sesid=" + sesid,
success:function(data){
$("#newdata").append(data);
});
} ///if end
} /// FUNC END
window.onscroll = yHandler;
load.php //
$osql=mysql_query("SELECT * FROM answer WHERE respond IS NOT NULL AND question_id='$did' AND id < '$newid' and pinned = '0' ORDER BY resp_time DESC LIMIT 5");
/// while loop which fetches data is below
If you don't want to or need to handle the case that other posts could show up via other means while the user is on this web page, then you can just set a flag when you got no more posts and check that flag and avoid the call to load.php if that flag is set.
// flag so we know when there are no more posts
var noMorePosts = false;
function yHandler(){
var id=$(".output:last").attr("id");
var split = id.split("output");
var newid=split[1];
var awrap = document.getElementById('awrap');
var contentHeight = awrap.offsetHeight;
var yOffset = window.pageYOffset;
var y = yOffset + window.innerHeight;
var sesid=$("#sesid").val();
if(!noMorePosts && y >= contentHeight){
// Ajax call to get more dynamic data goes here
$.ajax({
url:"load.php",
type:"POST",
data:'did=' + did + '&newid=' + newid + '&id=' + id + "&sesid=" + sesid,
success:function(data){
// pseudo code check to see if data was empty
// you fill in the actual test here
if (nothing in data) {
noMorePosts = true;
} else {
$("#newdata").append(data);
}
});
}
}
You could return from backend also the timestamp of the execution, then in client ask for this timestamp to retrieve or not data again. Just like caching works.
(I'll give you other alternative in a minute)
This could be another way (cache by request data):
function yHandler(){
yHandler.lastRequest = yHandler.lastRequest || null;
var id=$(".output:last").attr("id");
var split = id.split("output");
var newid=split[1];
var awrap = document.getElementById('awrap');
var contentHeight = awrap.offsetHeight;
var yOffset = window.pageYOffset;
var y = yOffset + window.innerHeight;
var sesid=$("#sesid").val();
if(y >= contentHeight){
// Ajax call to get more dynamic data goes here
var newRequest = 'did=' + did + '&newid=' + newid + '&id=' + id + "&sesid=" + sesid;
if(newRequest != yHandler.lastRequest){
$.ajax({
url:"load.php",
type:"POST",
data: yHandler.lastData,
success:function(data){
$("#newdata").append(data);
yHandler.lastData = newRequest; //Save the last request data
}
});
}
}
});
Basically, the above code saves the last request data. If in the next scroll it hasn't changed, then don't perform the ajax call.
Hope this helps. Cheers

Categories