I have been trying to debug for this days now, and I’m not sure what the problem is.
To give you a little background:
I'm working on a project that pulls the top headline on the politics section of a far left news source (Huffington Post), a moderate left (CNN), a moderate right (Fox), and a far right (Breitbart).
From here, I’m finding Reddit posts referencing that article and appending it to the html. All of this is being done through YQL.
Here's an example with how I'm using CNN.
//CNN
$(function getCNNNews() {
var statement = "select * from feed where url='http://rss.cnn.com/rss/cnn_allpolitics.rss'";
$.queryYQL(statement, "json", undefined, function (data) {
// do something with "data".
console.log(data.query.results.item);
//Get first object in array
console.log(data.query.results.item[0]);
var firstObjectCNN = data.query.results.item[0];
$("#col2").append("<h1 id='cnn'>" + firstObjectCNN.title + "</h1>");
$("#col2").append("<h4 id='cnn'> Published by CNN <br/>" + firstObjectCNN.pubDate + "</h4>");
//Search for the top post referencing that headline on Reddit
$(function getCNNPostReddit() {
var newStatement = encodeURIComponent(firstObjectCNN.title).replace(/'/g , "%27");
var statement = "select * from feed where url='https://www.reddit.com/search.xml?q=" + newStatement + "&sort=new'";
$.queryYQL(statement, "json", undefined, function (data) {
console.log(statement);
console.log(data);
var firstCNNEntryResults = data.query.results;
if (firstCNNEntryResults == null)
{
document.getElementById("loading2").style.display = 'inline-block';
}
else
{
// Get first entry's (which is the entry with the most comments) rss feed containing comments
var firstCNNEntry = data.query.results.entry[0];
console.log("select * from feed where url='" + firstCNNEntry.link.href + ".rss");
// Erase end of URL that's not needed
var firstCNNEntryLink = firstCNNEntry.link.href;
firstCNNEntryLink = firstCNNEntryLink.substring(0, firstCNNEntryLink.indexOf('?'));
console.log(firstCNNEntryLink);
//Create a dynamic rss feed based on link to first entry; this is where the comments will come from.
$(function getCNNRedditComments() {
var statement = "select * from feed where url='" + firstCNNEntryLink + ".rss'" ;
$.queryYQL(statement, "json", undefined, function (data) {
console.log(data.query.results.entry);
//Start with the 4th comment; since the first 3 comments are auto moderator
for (var i = 0; i < data.query.results.entry.length; i++) {
console.log(data.query.results.entry[i].content.content);
$("#col2 #comment-box").append("<div id='comment'><span id='username'>" + data.query.results.entry[i].author.name + "</span>" + ":" + data.query.results.entry[i].content.content + "</div>")
}
});
});
}
});
});
});
});
I've made it so when the results come out null, I replace the comments with a loading symbol. The issue I'm having is, sometimes the comments will show, and other times they won't.
The current state of the site is here:
leftright.info
Reddit has a limit to how often you can fetch their RSS feeds. I had that problem too, so I came up with a workaround. I've created a public tool for it on my website.
https://burkybang.com/reddit_rss
Related
I'm trying to build a simple tool that will return a Github profile when you search someone's username. Everything seems to be working, except when I search for a different user, the list of followers from the previous user search don't clear.
For example, a user who has seven followers will suddenly have dozens of follower avatars displaying.
Can anyone tell me how to display the correct number of followers unique to each user when fetching different Github profiles?
var response = null;
var followers = null;
document.getElementsByTagName('button')[0].addEventListener('click', function(r) {
getUser(document.getElementsByTagName('input')[0].value);
});
function getUser(name) {
fetch('https://api.github.com/users/' + name)
.then(function(r) {
console.log(r.status);
return r.json();
})
.then(function(j) {
response = j;
assignValues();
getFollowers(j.followers_url);
});
}
function assignValues() {
document.getElementById('loader').style = 'display: none';
document.getElementById('avatar').src = response.avatar_url;
document.getElementById('name').innerText = response.name;
document.getElementById('username').innerText = response.login;
document.getElementById('location').innerText = response.location;
document.getElementById('bio').innerText = response.bio;
document.getElementById('count').innerText = 'Followers: ' + response.followers;
}
function getFollowers(url) {
fetch(url)
.then(function(r) {
return r.json();
})
.then(function(f) {
followers = f;
listFollowers();
});
}
function listFollowers() {
followers.forEach(function(f) {
var li = document.createElement('li');
li.innerHTML = ''+ '<img src="' + f.avatar_url + '" alt="' + f.login + '"/>'+ '';
document.getElementById('list').appendChild(li);
});
}
You need to clear that #list element in listFollowers function before starting appending new followers to it. For example:
var list = document.getElementById('list');
list.innerHTML = '';
followers.forEach(function(f) {
var li = document.createElement('li');
li.innerHTML = ''+ '<img src="' + f.avatar_url + '" alt="' + f.login + '"/>'+ '';
list.appendChild(li);
});
Three sidenotes here:
why do you use global variables response and followers in your rendering functions when you can pass those as arguments?
as you rerender a 'user profile' first, then wait for avatars' fetch, it's still possible for a user to see the followers of user X when looking for user Y. It's better to clear that section (and show some visual cue for loading data) immediately after the user is switched.
as order of fetch responses is not guaranteed, there's a potential race condition here: if user clicks on that button twice (with different inputs), the earlier input might get back later - and overwrite the former. You need to guard against this, either by storing the latest input value and checking the response, or by some other means.
You can test those by artificially throttling the network speed. And believe me, in real world most of your user will have all sorts of problems with that.
I have this jzebra applet that I need to do some client side ticket printing.
This is the applets html definition:
<applet id="jzebra" name="jzebra" code="jzebra.PrintApplet.class" archive="../../../../../../web/org.openbravo.howtos/lib/jzebra.jar"
width="10px" height="10px">
The function I call in the form button is this:
function printDocument() {
var applet = document.jzebra;
var frm = document.frmMain;
var url = frm.elements["inpftpOBDir"].value;
var file ="0.txt";
var archivo = url + "/" + file;
if (applet != null) {
var printname = frm.elements["inpPrinterName"].value;
var indice = frm.inpPrinterSelected.selectedIndex;
var printselected = frm.inpPrinterSelected.options[indice].text;
alert(printname);
alert(printselected);
if(printselected == ""){
// printname = "zebra"
//alert('Default : ' + printname);
applet.findPrinter(printname);
monitorFinding();
} else {
//alert('Selected : ' + printselected);
applet.findPrinter(printname);
monitorFinding();
}
alert('File : ' + archivo);
// applet.findPrinter(printname);
applet.appendFile(archivo);
// Send characters/raw commands to printer
applet.print();
alert('The document was sent to the printer.');
}
}
I checked the console and there is a definition of applet, but when it reaches applet.findPrinter(printname), just explodes because applet.findPrinter is not a function.
Has anyone faced this struggle before? I have seen that there is a little gray square in the top left corner of my page. When I hover on it, it displays "undefined".
I finally came up with a very complex solution, having to use jnlp. I will post my code later for references, if anyone else find similar problems.
I have written a function to display some paragraph tags from an external webpage. For some reason the results are displayed in firebug console but not showing on the web page as I wanted (blank page).
function requestCrossDomain(callback){
var querylink = "select * from html where url='http://somedomain.com'" +
" and xpath='/html/body/div/div/div[2]/div/div/div/dl'";
var yql = 'http://query.yahooapis.com/v1/public/yql?q=' +
encodeURIComponent(querylink) + '&format=json&callback?';
$.getJSON(yql, function(data){
if (typeof callback === 'function'){
callback(data);
}
});
}
My firebug console shows the below value.
{"query":{"count":1,"created":"2013-12-23T06:31:46Z","lang":"en-US","results":{"dd":{"p":"Hills: High"}}}}
How can I modify the code to display the value of the P tag, which is "Hills: High"
I'm calling the function from HTML code and trying to display the value inside "#targetWrapper"
requestCrossDomain(function(results){
$('#targetWrapper').html(results);
});
Edited to reflect a functional fiddle
$(document).ready(function(){
requestCrossDomain();
});
function requestCrossDomain(){
var querylink = "select * from html where url='http://www.bom.gov.au/wa/forecasts" +
"/armadale.shtml' and xpath='/html/body/div/div/div[2]/div/div" +
"/div/dl'";
var yql = 'http://query.yahooapis.com/v1/public/yql?q=' +
encodeURIComponent(querylink) + '&format=json&callback?';
$.getJSON(yql, function(data){
$('#targetWrapper').html(data.query.results.dl.dd[0].p);
$("#targetWrapper").append("<br/><strong>" + JSON.stringify(data) + "</strong>");
});
}
Your data format was very much off the mark AND you cannot have two functions with the same name.
The object you get back from $.getJSON is a simple Javascript Object. You can access it just as you would any other object:
In this case, you'd use:
requestCrossDomain(function(results) {
$("#targetWrapper").html(results.query.results.dd.p);
}
I would highly recommend that you read the MDN documentation I linked above. Having MDN bookmarked is also a good idea; it's a great resource to have easy access to.
this is my first time here as a poster, please be gentle! I have zero knowledge of JS (yet, working on it) but am required to do some JS anyway. Here's my problem. I got some code (not mine) allowing a user to select multiple choices. I found the function that gathers these choices and store them
function getProductAttribute()
{
// get product attribute id
product_attribute_id = $('#idCombination').val();
product_id = $('#product_page_product_id').val();
// get every attributes values
request = '';
//create a temporary 'tab_attributes' array containing the choices of the customer
var tab_attributes = [];
$('#attributes select, #attributes input[type=hidden], #attributes input[type=radio]:checked').each(function(){
tab_attributes.push($(this).val());
});
// build new request
for (var i in attributesCombinations)
for (var a in tab_attributes)
if (attributesCombinations[i]['id_attribute'] === tab_attributes[a])
request += '/'+attributesCombinations[i]['group'] + '-' + attributesCombinations[i]['attribute'];
$('#[attsummary]').html($('#[attsummary]').html() + attributesCombinations[i]['group']+': '+attributesCombinations[i]['attribute']+'<br/>')// DISPLAY ATTRIBUTES SUMMARY
request = request.replace(request.substring(0, 1), '#/');
url = window.location + '';
// redirection
if (url.indexOf('#') != -1)
url = url.substring(0, url.indexOf('#'));
// set ipa to the customization form
$('#customizationForm').attr('action', $('#customizationForm').attr('action') + request);
window.location = url + request;
}
I need to make a simple display summary of these choices. After quite a bit of searching and findling, I came with the line with the DISPLAY SUMMARY comment, this one:
$('#[attsummary]').html($('#[attsummary]').html() + attributesCombinations[i]['group']+': '+attributesCombinations[i]['attribute']+'<br/>')
In the page where I want those options, I added an empty div with the same ID (attsummary):
<div id="attsummary"></div>
Obviously, it is not working. I know I don't know JS, but naively I really thought this would do the trick. May you share with me some pointers as to where I went wrong?
Thank you very much.
Correct form of the line it isn't working for you:
$('#attsummary').html($('#attsummary').html() + attributesCombinations[i]['group']+': '+attributesCombinations[i]['attribute']+'<br/>')
I am trying to create a Ajax function which will create an article navigation according to their date of creation, so the user can navigate through articles using previous(older) and next(newer) links.
<div class="content clear">
<div class="article">
Article contents...
</div>
EELMINE<span class="arrow_left"></span>
Tagasi nimekirja juurde<span class="arrow_middle"></span>
JÄRGMINE<span class="arrow_right"></span>
</div> <!-- End content -->
<script type="text/javascript">
$.ajax({
url: '/admin/api/site/articles.json?per_page=100',
dataType: 'json',
success: function(articles) {
$(articles).each(function(index, article) {
console.log(article);
$('div.article').fadeOut(0);
$('div.article:first').fadeIn(500);
$('a.leftarrow, a.rightarrow').click( function (ev) {
//prevent browser jumping to top
ev.preventDefault();
//get current visible item
var $visibleItem = $('div.article:visible');
//get total item count
var total = $('div.article').length;
//get index of current visible item
var index = $visibleItem.prevAll().length;
//if we click next increment current index, else decrease index
$(this).attr('href') === '#Next' ? index++ : index--;
//if we are now past the beginning or end show the last or first item
if (index === -1){
index = total-1;
}
if (index === total){
index = 0
}
//hide current show item
$visibleItem.hide();
//fade in the relevant item
$('div.article:eq(' + index + ')').fadeIn(500);
});
});
}
});
I'm having difficulties constructing the function responsible for getting the articles according to their date value.
Using console.log(article), I get the following values:
body: "..."
comments_count: 0
comments_url: "..."
created_at: "date and time ..."
excerpt: "..."
title: "..."
url: "..."
So it should be possible to use the created_at variable for the navigation, but I don't know how at the minute.
Any ideas?
CMS used: Edicy
Note: The CMS does not support PHP.
EDIT: The article listing sample on the "blog" page provided by the CMS developer documentation.
The easier way to do it is use your model as much as you can, and do it with sql "limit"
I don't know what database do you use, so I'll make some steps with mysql database.
I'm confuse with your code, why you call ajax without nothing press? or you are hiding some code?
Let me try with this code:
assume that you have a container div and 2 static navigation button
Next
Back
<div id="container"></div>
<script>
$("#next, #back").click(function(){
//get page number
//0 means no page to load
var page = $(this).data("page");
if(page == 0)return false;
$.ajax({
url : "your/url/?page=" + page,
dataType: "json",
success : function(data){
var container = $("#container");
$.each(data, function(index, article){
container.append(article); // or do something you want
});
if($this.attr("id") == "next") $("#next, #prev").data("page", $this.data("page") + 1);
else $("#next, #prev").data("page", $this.data("page") - 1);
}
});
});
</script>
for the backend :
<?php
$page = $_GET["page"];
$perPage = 100;
$start = ($page - 1) * $perPage; // minus 1, because limit start from 0
$sql = "SELECT * FROM table WHERE 1=1 LIMIT $start, $perPage";
//execute the sql and get the result (ex. result)
echo json_encode($result);
I wish my answer will help you.
I checked the API on edicy, seems like it doesn't allow you to filter by created_at.
But based on your code, you can use query string to get the current index of the article in a specific page.
For example:
Start with http://insenerid.edicy.co/uudised/2013/, it is also called page 1. There are 4 articles and you have to add ?page=1&index={0..3} to each article URL like this:
from http://insenerid.edicy.co/uudised/2013/aasta-ehitusprojekt-2012-tiitli-kandidaadiks
to http://insenerid.edicy.co/uudised/2013/aasta-ehitusprojekt-2012-tiitli-kandidaadiks?page=1&index=1 (because it's the second article in page 1)
Then, modify your code:
// This is for example: page = 1, index = 1
// You have to write extra code to get the query string you need.
var page = 1, index = 1;
$.ajax({
url: '/admin/api/site/articles.json?per_page=100&page=' + page,
// ...
// Replace
// $('div.article:first').fadeIn(500);
// with
$('div.article:eq(' + index + ')').fadeIn(500);
If your question is how to sort the data received by your ajax call,
you could simply use the array.sort([compareFunction]) before to use them.
(see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)
like this:
...
success: function(articles) {
articles.sort(function (a, b) {
var d1 = new Date(a.created_at);
var d2 = new Date(b.created_at);
if (d1 < d2) return -1;
if (d1 == d2) return 0;
return 1;
});
$(articles).each(function(index, article) {
// alert(article.created_at);
console.log(article);
....