Twitter API and Node - javascript

I'm trying to retrieve my last tweet from Twitter with https://github.com/jdub/node-twitter
I want to declare a variable, change that variable within a function, then use it again outside that function. Is this possible?
I have authenticated and can see my last tweet if I do:
var tweet;
twit.get('http://api.twitter.com/1/statuses/user_timeline.json', function(data) {
tweet = data[0].text;
console.log(tweet);
});
But I want to separate my code out and do:
var tweet;
twit.get('http://api.twitter.com/1/statuses/user_timeline.json', function(data) {
tweet = data[0].text;
});
console.log(tweet);
Tweet is still undefined.
Please educate me :-)

You want to be able to console.log immediately but node.js is not synchronous and that's what makes it so powerful and fast. You have to get used to an asynchronous pattern of coding with node.js. The get request is async. Tweet doesn't get assigned until the callback happens.
Console.log executes immediately after the async request is made.
Try: (EDIT- I suggested this and then question was edited to include this code)
twit.get('http://api.twitter.com/1/statuses/user_timeline.json', function(data) {
tweet = data[0].text;
console.log(tweet); // executed after call returns
});
// executes immediately after request is sent
console.log("request sent");
Notice that the second argument to the twit.get call is an anonymous function that will get executed after it has completed the async request.
The output of this should be "request sent" and then the tweet result in that order.

Related

JS onclick, override previous click

I am writing a query engine where the user enters parameters and then clicks query.
The ng-click event can take up to 7-10 seconds, but rendering of page 1 takes less than a second. If a user wants to re-submit a new query before that time is up there is a bit of a lag because I believe the original function call is still returning.
Is there a way to abruptly stop any previous function calls and only call the most recent?
Below is the query function and the call from the HTML
$scope.query = function(name, matchMode, domain) {
name = name.trim();
$scope.pageNumber = 0;
start = 0
end = $scope.perPage;
$http.get(ROOT_API+"query/asset/"+name+"/"+matchMode+"/"+domain).success(
function(data){
$scope.results=data;
$scope.displayResults=$scope.results.slice(start,end);
$scope.totalResults=data.length;
$scope.totalPages=Math.floor($scope.totalResults / $scope.perPage);
setPageValues($scope.displayResults)
});
setTimeout(function() {
$scope.displayResults.concat(setPageValues($scope.results.slice(end,$scope.totalResults)))
},2000);
}
<input ng-model="queryName" placeholder="name">
<input ng-model="matchMode" placeholder="match mode" defaultValue="ANYWHERE">
<input ng-model="domain" placeholder="domain" defaultValue="ANY">
<button ng-click="query(queryName, matchMode, domain)">QUERY</button>
Your code has gone in multiple threading,
first thread has been assigned to code inside you click function from where it has been started and the second one assigned to http get request. so first thread gets executed as it ignores next thread execution.
For that sake in javascript, we have callback functions for handling the async calls.
instead of using setTimeout function, record the API call response in callback.
let apicallFun = function(requestObj, Callback){
console.log("Inside API call");
return $http.get('/your_URL', requestObj)
.then(function(response){
Callback(response);
})
}
and then inside your click function call this apicallFun as:
$scope.clickFun = function(requestObj){
apicallFun(requestObj, function(response){
//according to your response object write the rest of your code.
}
}
Maybe you could wrap the whole thing in a do..while loop and have some exit variable you can set to true?

Method ends before $.getJson finishes running

I have the follow code using jQUery's getjson methods
function Share(){
var title = 'Hello';
var description = 'hi description';
var url = "www.facebook.com"
$.getJSON("http://getTitle/1", function(data){
title = data.Name;
});
callShare(title,description,url,imageUrl);
}
function callShare(title,description,url,imageUrl){
window.open(
'http://www.facebook.com/sharer.php?s=100&p[title]='+title+'&p[summary]='+description+' &p[url]='+url+'&p[images][0]='+imageUrl+'','facebook-share-dialog',
'width=626,height=436')}
However, it seems that the method finishes running and does the callShare function before the getJson method has finished running. Would require some help here. I understand that there might be duplicate question here and I apologize but I am not able to apply it here.
Thanks
$.getJSON("http://getTitle/1", function(data){
title = data.Name;
callShare(title,description,url,imageUrl);
});
Being an async function $.getJson() doesn't wait for the response and executes the next line.
If you want to do some things after the response has been received from the server put it in the success function. Like I have mentioned in the code.
if you also want to execute code on error or before sending the request. Use $.ajax() instead
Althoug the question has been answered by Parv but here are some explanation
First of all the correct way to call functions in such senarios
$.getJSON("http://getTitle/1", function(data){
title = data.Name;
callShare(title,description,url,imageUrl);
});
Now the question is why?
$.getJSON is an extension of $.ajax method i.e. Asynchronous, so the browsers expect of waiting for the request to complete by $.getJSON they move on to the next line of codes so that the user dont get stuck with lock browser waiting for a request to complete.
Now what is the solution in that case?
Such Asynchronous requests have a or couple of special methods called call backs, so all you need is to call such methods in those call backs that are required to be called after the successful failed or complete of the request, you will find more in the above link
$.getJSON is just a shorthand for $.ajax. As others pointed out, its an async call which will run in a separate thread(kind of) and rest of the code will keep on executing without worrying for the JSON result.
So you can add a success function which will be called when the async call succeeds. You can use $.ajax too.
$.ajax({
dataType: "json",
url: url,
data: data,
success: callShare(title,description,url,imageUrl),
error: alert('error');
});
I use $.ajax because it gives more clarity over the things that are happening.

How Do I return a javascript variable from a function that contains a $.get() request

I've tried Googling this but could not reslove it. It may seem like a really simple issue to others but I'm baffled by it. I have the below code in which I get undefined for the first alert but I still get the correct values in the 2nd alert. BUT if I comment out the first alert (just the line with alert) then the 2nd alert output becomes undefined. Can any one explain why this is and how I may output the 2nd alert correctly without the first one, any Help is greatly appreciated.
function getDetails(ID){
var qArray = [];
$.get('get_Question', {"Id":ID}, function(){})
.success(function(data){
var json = $.parseJSON(data);
qArray.push(json.value1);
qArray.push(json.value2);
});
//First Alert
alert("-> "+qArray[0]);
return qArray;
}
This is the 2nd alert which calls the above method:
var myArray = getDetails(4);
alert("myArray [0]: "+myArray[0]);
You can't return a value, the $.get() call is asynchronous.
You need to defer any operations on qArray until the AJAX call has completed, i.e. inside the callback.
Better yet, use deferred callbacks:
function getDetails(ID) {
return $.get('get_Question', {"Id":ID})
.pipe(function(json) {
return [json.value1, json.value2];
});
}
The .pipe deferred function creates a new promise which will ultimately return the desired array, but only once the AJAX call has completed.
You would then use this like this:
getDetails(ID).done(function(qArray) {
alert("-> " + qArray[0]);
});
Note that $.get() doesn't directly support error callbacks, but with deferred objects you can get access to them:
getDetails(ID).done(function(qArray) {
alert("-> " + qArray[0]);
}).fail(function(jqXHR, textStatus, errorThrown)) {
alert("The AJAX request failed:" + errorThrown);
});
Without this you'd need to build the error handling directly into the getDetails() function and then require some mechanism to tell the rest of the application logic about the error.
NB I've assumed that you don't really need to call JSON.parse() manually - if your web server returns the right Content-Type header then jQuery will do that for you automatically.
Ajax calls happens asynchroniusly, meaning you can't wait for the call to return and get the value. The way to do it is to employ a callback. Your example will become something similar to this:
function getDetails(ID, callback){
$.get('get_Question', {"Id":ID}, function(){})
.success(function(data){
var qArray = [];
var json = $.parseJSON(data);
qArray.push(json.value1);
qArray.push(json.value2);
callback(qArray)
});
}
Calling it will change a bit:
getDetails(4, function (myArray) {
alert("myArray [0]: "+myArray[0]);
});
The First Alert is called before the ajax call is finished, so the variable is still undefined.
This is because the $.get() is done asynchronously. There is no option for $.get() to pass parameter for async calls, so you should use $.ajax() instead and pass a param async: false
The $.get call creates a new asynchronous request for the resource in question.
When you call the first alert it is undefined because the request hasn't been completed yet. Also since you are forced to pause on the alert the request has time to be completed in the background. Enough time for it to be available by the second alert.
The same thing happens when you comment out the first alert. This time the second alert is called before the request is completed and the value is undefined.
You need to either make your requests synchronous or consider continuing execution after receiving the response by using a callback function within the success callback function you have already defined in $.get.
As several others have said, ajax-request are asynchronous. You could however set the async property to false to get a synchronous request.
Example:
function getDetails(ID) {
var result = $.ajax('get_Question', {
async : false,
data : { 'Id' : ID }
});
// do something with the result
return result;
}
I myself would have use a callback function instead beacuse async:false is bad practice and is also deprecated.
You'll need to rewrite $.get to use $.ajax and specify async: false
AJAX is asynchronous: you can't tell when the request will complete. This usually means you need to pass callback methods that will be called with the result of the request when it completes. In your case this would look something like:
function getDetails(ID, callbackFunc){
$.get('get_Question', {"Id":ID}, function(){})
.success(function(data){
var qArray = [];
var json = $.parseJSON(data);
qArray.push(json.value1);
qArray.push(json.value2);
callbackFunc(qarray);
});
}
getDetails(4, function(qArray) {
alert("myArray [0]: "+qArray[0]);
};

I'm new to javascript and I'm fetching JSON data from url, I'm only able to access data in success function, Am I missing something?

Here is the code :-
var quiz;
function startQuiz() {
$.ajax({
url: 'get_quiz/',
cache: 'false',
dataType: 'json',
async: 'false',
success: function(data) {
quiz = data;
alert(quiz[0].q); // I'm able to access quiz here
},
}
);
}
startQuiz();
alert(quiz[0].q); // Not able to access it here.
I'm not able to access quiz here, am I mission something?, Whats wrong with this?
Ajax is assynchronous which can be an unfamiliar concept. Your code will run like this:
1. var quiz;
2. define function startQuiz;
3. call startQuiz;
4. do ajax call (and continue! don't block)
5. alert(quiz[0].q); // Not able to access it here.
-- ajax call comes back
6. quiz = data;
7. alert(quiz[0].q); // I'm able to access quiz here
Ajax is asynchronous, it doesn't block. This means that when you make the ajax call the callback doesn't actually get called until the ajax call returns, it doesn't block and wait. Instead the code will continue on.
Then later when the ajax call returns the data, your callback function will be executed.
Javascript does this by means of an event loop.
See it like this: steps 1-5 are part of the first event. 6-7 are part of the second event.
A cool thing about JavaScript is that in your callback you still have access to anything above it (like the variable quiz) because of scoping. This is called a closure. Your callback function closes around the scope and brings it with him to the next event.
AJAX calls are asynchronous, you should wait for the result to come back from the server. Either do all the work in a callback function or have a look on a promises library (I like Q promises library), which makes waiting for AJAX results very easy.
This is due to the asynchronous nature of JavaScript, once you call startQuiz() it executes and jumps back out and executes your quiz alert().
You have to access your quiz data explicitly after the callback is called to make sure you have access to it.
You also have to worry about scoping, as you may not be actually modifying the same quiz variable.
var quiz,
fetched = false;
$.ajax({
//blah
success : function(data){
fetched = true;
quiz = data;
}
});
setInterval(function(){
if(fetched){
//quiz is populated
}else{
//quiz hasn't be populated yet
}
},50);
Although not a clever example, I'm just trying to get the point across that startQuiz() doesn't wait for the ajax call. The A in AJAX mean asynchronous.
You should give jQuery deferreds a try which ist the preferred way of writing ajax related code since jQuery 1.5: http://javascriptplayground.com/blog/2012/04/jquery-deferreds-tutorial
Once you get the hang of it maybe will be easier to write and understand your code.

How do I store the result of an ajax call in a function using jQuery?

I have the folowing code:
function checkPermission(user) {
var result = 'default';
$.get('/mymodule/checkPermission.php?user=' + user, function(data) {
result = data; // does not store data into result, why ?
if (result == 'no') {
$('.sorry_msg').show();
}
});
alert(result); // shows "default".
return result == 'yes';
}
Can you explain why this doesn't work. The problem is that I cannot store the data variable into result, see comments in the code. I guess it is because of the anonymous function, but I don't know javascript enough to understand exactly what happens.
Also, how can return true or false in checkPermission function based on the result of the ajax call ?
You don't get the expected result because the ajax callback function is executed asynchronously. This means that the process doesn't wait for the ajax call to finish. Therefor, before the ajax call has executed the callback function, the outer function checkPermission is already terminated and it's return value will therefor not have been altered by the ajax callback.
#pinouchon:
I've seen your suggested solution, but I would advise against using synchronous ajax requests, as this will block the whole user interface of the browser for the time it has to wait for the result of the ajax request. I'd suggest you rethink your execution strategy, and build it around asynchronously executed ajax requests.
jQuery's get() method is an AJAX call, therefore Asynchronous with your method. The function that is called at completion of the get() call, the one that changes the result value, executes AFTER your existing alert. Try this:
$.get('/mymodule/checkPermission.php?user=' + user, function(data) {
result = data; // does not store data into result.
alert("Ajax Complete!"); // NEW ALERT CALL - called upon Ajax Completion
if (result == 'no') {
$('.sorry_msg').show();
}
});
You'll see the order of the Alerts is "default" and then "Ajax Complete!"
The entire purpose of the callback function is to ensure that you are able to execute some code upon completion of the request.

Categories

Resources