jQuery use variable outside function - javascript

I'm using jquery.feeds.js to aggregate rss feeds and preprocessing the data received with jsonp.js. The problem is I can't use the variable summarize I've set within the preprocess function outside of it. I did set it as a universal variable though so I don't know what I could be doing wrong. Could it be a problem that I'm running multiple JSON requests?
My code:
$('#feed').feeds({
feeds: {
reuters: 'http://feeds.reuters.com/reuters/businessNews'
},
max: 2,
preprocess: function ( feed ) {
var articleLink = (this.link);
var summarize = '';
$.getJSON({
url: 'https://jsonp.nodejitsu.com/?url=http://clipped.me/algorithm/clippedapi.php?url='+articleLink+'&callback=?',
corsSupport: true,
jsonpSupport: true,
success: function(data){
var summarize = data.summary
}
});
alert(summarize);
this.contentSnippet = summarize
},
entryTemplate: '<h3><!=title!></h3><p><!=contentSnippet!></p><i><!=link!></i>'
});
And a JSFIDDLE

You have a series of errors that are not addressed in the other posts..
the preprocess callback allows for changes in the current object (feed) right before it gets displayed.
Since the getJSON is an ajax call it will get the results too late. And changing the contentSnippet even in the success callback will not fix this.
You use the $.getJSON method as if it was $.ajax. So you pass it wrong arguments. Just use $.ajax for your syntax
finally to fix the first issue, you need to alter your template a bit so you can find the relevant parts later on (when the ajax requests complete) and use the onComplete callback instead (of the feeds plugin)
All changes together give
$('#feed').feeds({
feeds: {
reuters: 'http://feeds.reuters.com/reuters/businessNews'
},
max: 2,
onComplete: function(entries){ // use onComplete which runs after the normal feed is displayed
var $this = $(this);
entries.forEach(function(entry){
var $self = $this.find('.entry[data-link="'+entry.link+'"]');
$.ajax({
url:'https://jsonp.nodejitsu.com/?url=http://clipped.me/algorithm/clippedapi.php?url='+entry.link,
corsSupport: true,
jsonpSupport: true,
success: function(data){
// add the results to the rendered page
$self.find('.snippet').html( data.summary );
}
});
});
}, // change the template for easier access through jquery
entryTemplate: '<div class="entry" data-link="<!=link!>"><h3><!=title!></h3><p class="snippet"><!=contentSnippet!></p><i><!=link!></i></div>'
});
Demo at http://jsfiddle.net/gaby/pc7s2bmr/1/

I think you mean this
$('#feed').feeds({
feeds: {
reuters: 'http://feeds.reuters.com/reuters/businessNews'
},
max: 2,
preprocess: function ( feed ) {
var articleLink = (this.link);
var summarize = '';
var that = this;
$.getJSON({
url: 'https://jsonp.nodejitsu.com/?url=http://clipped.me/algorithm/clippedapi.php?url='+articleLink+'&callback=?',
corsSupport: true,
jsonpSupport: true,
success: function(data){
that.contentSnippet = data.summary
}
});
},
entryTemplate: '<h3><!=title!></h3><p><!=contentSnippet!></p><i><!=link!></i>'
});

Mathletics is correct. Do this...
$('#feed').feeds({
feeds: {
reuters: 'http://feeds.reuters.com/reuters/businessNews'
},
max: 2,
preprocess: function ( feed ) {
var articleLink = (this.link);
var summarize = '';
var _this = this;
$.getJSON({
url: 'https://jsonp.nodejitsu.com/?url=http://clipped.me/algorithm/clippedapi.php?url='+articleLink+'&callback=?',
corsSupport: true,
jsonpSupport: true,
success: function(data){
_this.contentSnippet = data.summary
}
});
alert(summarize);
},
entryTemplate: '<h3><!=title!></h3><p><!=contentSnippet!></p><i><!=link!></i>'
});

Related

Calculating the Time of an ajax Response and use that time in SetTimeout function

I am trying to get the response time of an ajax request and use it in a setTimeout() function, this function displays a loader that is suppose to keep loading until we get the response.
Here's my function :
$("#recalculer").click(function(){
ajax_call();
setTimeout(function()
{
$("#divgris").fadeTo(0,1);
$("#loadingdiv2").hide();
}, 5000);
});
And here's my ajax request :
function ajax_call()
{
var resultat;
var duree_souhaitee= $("#duree").val();
var apport_personnel= $("#apport").val().replace(/\s+/g, '');
var prix_achat_bien=$("#prix").val().replace(/\s+/g, '');
$.ajax({
type: "POST",
url: "/iframe/rest-assurance",
data : {
"duree_souhaitee" : duree_souhaitee,
"apport_personnel" : apport_personnel,
"prix_achat_bien" : prix_achat_bien
},
dataType: 'json',
xhrFields: {
withCredentials: true
},
async: true,
beforeSend: function(){
$("#actualiserAssurance").hide();
},
success: callback_assurance
});
}
For now i set a time of 5000 but i need to replace it with the ajax response time, how can I achieve that ?
I use always:
$("#loadingdiv2").show();
$.ajax(
...
).always(function(){ $("#loadingdiv2").hide(); });
If you want to separate it from the Ajax call I would use a custom event.
$("#recalculer").click(function(){
ajax_call();
});
$("body").bind('custom.ajaxStart', function(){ $("#loadingdiv2").show(); });
$("body").bind('custom.ajaxStop', function(){ $("#loadingdiv2").hide(); });
function ajax_call(){
$('body').trigger('custom.ajaxStart');
$.ajax(..).always(function(){ $('body').trigger('custom.ajaxStop'); });
}
The always callback is triggered even on a 404, relying on timing never works well for me.
Using an event gives you the flexibility of calling the loading deal, from anywhere.
Meaby the you can use:
console.time(label);
and
console.timeEnd(label);
more info can be found here.
Goodluck!
use
var afterfnc = ()=>{
$("#divgris").fadeTo(0,1);
$("#loadingdiv2").hide();
}
and then set
callback_assurance = afterfnc
in ajax call

Is using jQuery clever to download multiple template-files?

I want to download and cache multiple mustache-templates and the only real way I know to do this is by downloading them via the jQuery.ajax()-method.
So my straightforward preload-init code looks a little ... ugly!
function getAllTemplatesUglyAndNotPerformant() {
//this is no longer valid, stays just for reference; look at the bottom for the solution
//easy - preload the template and execute it to the data
$.ajax({
url: 'fragments/employee.mustache',
success: function (employeeTpl) {
//uh-oh async process-handling forces me into digging this deeper
$.ajax({
url: 'fragments/employee_day.mustache',
success: function (dayTpl) {
//third level - now i am puzzled already
$.ajax({
url: 'fragments/employee_day_regular.mustache',
success: function (protodayTplRegular) {
//monologue: am i doing this right?
$.ajax({
url: 'fragments/employee_day_deleted.mustache',
success: function (protodayTplDeleted) {
//most probably not
var cachedTemplates = {
employee: employeeTpl,
day: dayTpl,
protoday: {
regular: protodayTplRegular,
deleted: protodayTplDeleted
}
};
//shoot, i also cannot return cachedTemplates, better bury my init-method in this!
init(cachedTemplates);
}
});
}
});
}
});
}
});
}
//initializes downloading and parsing data to what will be seen
function init(cachedTemplates) {
//get the data
$.ajax(
url: '_get_data.php',
success: function (data) {
if (data.success) {
$.each(data.employees, function (iEmployee, vEmployee) {
//this goes through a custom rendering for an employee and his sub-nodes stored in arrays (all rendered in Mustache)
var employee = parseEmployee(vEmployee);
var html_employee = employee.render(cachedTemplates);
$('#data-position').append(html_employee);
});
}
//ignore what may else happen for now
}
)
}
Is there a better way for downloading multiple files for caching in JS?
EDIT:
my rewrite of getAllTemplates() looks now more like this and is finally "more-understandable" and performant for the next one to touch "Peters Legacy":
function getAllTemplates() {
$.when(
$.get('fragments/employee.mustache'),
$.get('fragments/employee_day.mustache'),
$.get('fragments/employee_day_regular.mustache'),
$.get('fragments/employee_day_deleted.mustache')
)
.done(function (employeeTpl, acquisitionTpl, protodayTplRegular, protodayTplDeleted) {
var cachedTemplates = {
employee: employeeTpl[0],
acquisition: acquisitionTpl[0],
protoday: {
regular: protodayTplRegular[0],
deleted: protodayTplDeleted[0]
}
};
init(cachedTemplates);
});
}
You don't specify which version of jQuery you're using, so here's assuming you're using a somewhat current build;
You can use $.when() which is in jQuery 1.5+.
$.when() allows you to bundle (essentially) a bunch of async methods (ajax in this case) and wait until all of them have completed. In your example you are firign one request, waiting for the response and then firing another. With $.when(); if your connection allows it they can all fire simultaneously, saving a lot of time in your example!
something like:
$.when(
$.ajax( "fragments/employee.mustache" ),
$.ajax( "fragments/employee_day.mustache" ),
$.ajax( "..." )
)
.done(function( employeeRes, dayRes ) {
// the first item in array should be the data
var employeeTpl = employeeRes[0];
var dayTpl = dayRes [0];
// ...
});
There's loads of good examples at the jQuery Website

jQuery DataTables duplicates are initially loading

So, adding on to my question from yesterday: jQuery AJAX call function on timeout
Using the first answer from the post from yesterday, the table does indeed reload without refreshing the whole page. It does so after 30 seconds.
But my problem lies before the first refresh...
The page loads, and the records are duplicated. But after the first refresh and every refresh after (unless I manually refresh using F5), everything is fine. No duplicates.
I'm trying to figure out why there are duplicates and how to remove the duplicates upon the page's initial ready event.
Here is the code, starting with the ready event:
$(document).ready(function()
{
$.ajax({
url:'api/qnams_all.php',
type:"GET",
dataType:"json"
}).done(function(response) {
console.log(response.data);
renderDataTable(response.data)
}).fail(function() {
alert( "error" );
}).always(function() {
alert( "complete" );
});
});
Here is the function to load the DataTable:
function renderDataTable(data)
{
var $dataTable = $('#example1').DataTable({
"ajax": 'api/qnams_all.php', // just added this
"data": data,
"bDestroy": true,
"stateSave": true
});
// then I add the reload function
setInterval( function () {
$dataTable.ajax.reload();
}, 30000 );
});
As stated above, the setInterval function works like how it should. It's just the initial page load is duplicating all of the records.
Does anyone see why and how to fix it?
I think you've got some duplication going on. You don't need to load the ajax flie and then load it again when you set up the DataTable.
Try replacing all of your code with this:
$(document).ready(function() {
// load and render the data
var $dataTable = $('#example1').DataTable({
"ajax": 'api/qnams_all.php', // just added this
"data": data,
"bDestroy": true,
"stateSave": true,
// the init function is called when the data table has finished loading/drawing
"init": function() {
// now that the initial data has loaded we can start the timer to do the refresh
setInterval(function() {
$dataTable.ajax.reload();
}, 30000);
}
});
});
Calling clear prevents duplicate rows while loading data into table:
$("#checkResourcesButton").click(function() {
$.post("./get/resources", {
featureName: $('#myvar').val()
}).done(function (data) {
var table = $('#table-output').DataTable();
table.clear();
var json = JSON.parse(data);
for (var row in json) {
var nameVal = json[row].Name;
var emailVal = json[row].emailId;
var roleVal = json[row].role;
var startDateVal = json[row].startDate;
var endDateVal = json[row].endDate;
var toAdd =
{
name: String(nameVal),
emailId: String(emailVal),
role: String(roleVal),
startDate: String(startDateVal),
endDate: String(endDateVal)
};
table.row.add(toAdd);
}
table.draw();
});
});

jQuery access vaules of global variable form one function to another

I am working in jQuery and I have a variable that I declared as global in one function and when I alert it it gives me right result but now I want to access the same variable in another function and alert it in another function it gives me empty result mean I cannot access it over there. I know about the scope of a variable but to overcome it I decleared variable as global but I am still unable to access it.
Here is my first function:
var employee_email = '';
function showCustomer()
{
// fire off the request to ajax_stufflist.php
request = $.ajax({
url: "ajax_stufflist.php?"+url,
type: "post",
success: function(data){
if(data != ''){
var response = $(data).find("#gmp_stuff").html();
employee_email = $(data).find(".EMP_EMAIL>span").html();
//alert(employee_email);
$("#user_responses").html(response);
$(function() {
$("#user_responses").dialog({
dialogClass:'transparent',
resizable: false,
draggable: false,
modal: true,
width: 1000,
autoOpen: false,
overlay: { opacity: 0 }
});
$('#user_responses').dialog('open');
$('#user_responses').css('display','');
});
}
},
error:function(){
alert("failure");
$("#user_responses").html('error occured');
}
});
}
In this function the variable employee_email is decleared above the function and I want to access the same variable with value in other function just next to it in same script tag.
function sendEmail(){
alert(employee_email );
request = $.ajax({
url: "send_email.php?"+employee_email ,
type: "post",
success: function(data){
$("#email_responses").html();
},
error:function(){
alert("failure");
$("#email_responses").html('error occured');
}
});
}
Kindly tell me what's wrong with it. Thanks in advance for any kind of help.
This is not a problem of scope. If it would have been, you would have got an error in your console. But you are getting an empty result because either the AJAX call is not complete yet or it has not been able to change the value due to some error there. Try this.
Define:
var flag = false;
Your success function should be:
success: function (data) {
if (data != '') {
var response = $(data).find("#gmp_stuff").html();
employee_email = $(data).find(".EMP_EMAIL>span").html();
//alert(employee_email);
$("#user_responses").html(response);
//$(function () {
$("#user_responses").dialog({
dialogClass: 'transparent',
resizable: false,
draggable: false,
modal: true,
width: 1000,
autoOpen: false,
overlay: { opacity: 0 }
});
$('#user_responses').dialog('open');
$('#user_responses').css('display', '');
//});
flag = true;
}
}
And sendEmail() can be:
function sendEmail(){
if(flag)
{
request = $.ajax({
url: "send_email.php?"+employee_email ,
type: "post",
success: function(data){
$("#email_responses").html();
},
error:function(){
alert("failure");
$("#email_responses").html('error occured');
}
});
}
else
alert('Sending email is unavailable currently. PLease try after some time.');
}
Even though this have been answered hundreds of times on SO, I can give you a short explanation.
Since you're dealing with 2 asynchronous calls, you can never access data from the first call in a normal syncronous flow.
Make your first function return your $.ajax
function showCustomer(){
return $.ajax({ /* ... */ });
And access the data returned in a callback:
showCustomer().done(function(data){
console.log($(data).find(".EMP_EMAIL>span").html());
});
This assumes that you're using jQuery 1.5 or above, where the ajax calls exposes a promise.
An other alternative would be to nest the ajax calls (call the second one in the first ones success handler).
You're updating the value employee_email through AJAX call. As soon as first function is called, it makes AJAX call and moves to second function. The second function won't see the value change yet and employee_email doesn't change at all.
You've 2 options -
Use second function in done of first function.
Use Deferred object in first call and on done of it call the second function.

Why does my array appear empty when calling a function after the array is built in JS

// variables to be used throughout
var videos = new Array();
// similar artist/bands
function similarTo(who) {
$.getJSON('http://ws.audioscrobbler.com/2.0/?method=artist.getsimilar&artist='+who+'&limit=20&api_key=b25b959554ed76058ac220b7b2e0a026&format=json&callback=?', function(data) {
$.each(data , function(i,similars) {
$.each(similars.artist, function(c, artist) {
$.getJSON('http://gdata.youtube.com/feeds/api/videos?q='+artist.name+'&orderby=relevance&start-index=1&max-results=1&v=2&alt=json-in-script&callback=?', function(data) {
$.each(data.feed.entry, function(i,video) {
videos.push({
id: video.id.$t.split(":")[3],
title: video.title.$t
});
});
});
});
initPlaylist();
});
});
}
// start the playlist
function initPlaylist() {
$('#ytplayerid').load('includes/ytplayer.php?track=' + videos[currenttrack].id);
$('#player span').html(videos[currenttrack].title);
}
When my code reaches the initPlaylist() function the videos array appears to be empty, I have a feeling its actually being fired before the $.getJSON() call... is this possible? If I add a console.log(videos) after each push() the array is actually being built.
$.each(similars.artist, function(c, artist) {
// doing ajax stuff here
$.getJSON('url', function(data) {
// this will get called later
$.each(data.feed.entry, function(i,video) {
videos.push({
id: video.id.$t.split(":")[3],
title: video.title.$t
});
});
});
});
// trying to manipulate ajax data now :(
initPlaylist();
Your videos is empty because your trying to manipulate it before it's ready.
What you want to do is use jQuery 1.5+ deferred objects
var ajaxs = $.map(similars.artist, function(artist, c) {
return $.getJSON('url', function(data) {
$.each(data.feed.entry, function(i,video) {
videos.push({
id: video.id.$t.split(":")[3],
title: video.title.$t
});
});
});
});
// when all the ajaxs finish then call init play list
$.when.apply($, ajaxs).then(initPlaylist);
Move initPlaylist to a point where videos exists:
function similarTo(who) {
$.getJSON('http://ws.audioscrobbler.com/2.0/?method=artist.getsimilar&artist='+who+'&limit=20&api_key=b25b959554ed76058ac220b7b2e0a026&format=json&callback=?', function(data) {
$.each(data , function(i,similars) {
$.each(similars.artist, function(c, artist) {
$.getJSON('http://gdata.youtube.com/feeds/api/videos?q='+artist.name+'&orderby=relevance&start-index=1&max-results=1&v=2&alt=json-in-script&callback=?', function(data) {
var videoes = []; //create array
$.each(data.feed.entry, function(i,video) {
videos.push({
id: video.id.$t.split(":")[3],
title: video.title.$t
});
});
initPlaylist();
//videos exists, but i think you might need to pass it as a parameter
});
});
});
});
}
Although, knowing what is in initPlaylist(); might help. And it might solve what appears to be a scope problem in your code.
ALSO: Ajax is asynchronous, there forit might not finish by the time the code gets to initPlaylist();, so you need some type of callback to call initPlaylist(); when all the ajax calls are done.

Categories

Resources