Make FB.api() calls synchronous - javascript

I am creating fQuery API on top of FB javascript SDK. And till now everything worked fine, but i got stuck in FB.api calls now.
Actually, I am trying to load facebook user object i.e. "/me" using FB.api function.
function somefunc() {
var r = fQuery.load(selector); //selector = "me"
return r;
}
fQuery.load = function( selector ) {
fQuery.fn.response = "";
return FB.api( "/" + selector, function (response) {
// we get response here.
});
}
Is it possible to return the response or can we make it sync call. I have tried many ways to work around but could not get success.
Please provide suggestions.

If you think about it, you don't really want to make it synchronous. Javascript is single threaded by nature, making something that is asynchronous synchronous, would involve "freezing" the thread until the asynchronous call returns.
Even if you could do it, you don't want to, trust me.
Redesign your code to work with the asynchronous nature instead of fighting it. you will create better applications, have happier users and become a better coder all at the same time.

As commented elsewhere, making a synchronous call is useful if you want to open a popup after a successful response as browsers will often block popups that aren't a result of a direct user action.
You can do this by manually calling the Open Graph API with JavaScript (or jQuery as per the example below) rather than using the Facebook JS SDK.
e.g. to upload a photo via the Open Graph API and then prompt the user to add it as their profile picture using a popup, without the popup being blocked:
$.ajax({
type: 'POST',
url: 'https://graph.facebook.com/me/photos',
async: false,
data: {
access_token: '[accessToken]',//received via response.authResponse.accessToken after login
url: '[imageUrl]'
},
success: function(response) {
if (response && !response.error) {
window.open('http://www.facebook.com/photo.php?fbid=' + response.id + '&makeprofile=1');
}
}
});

You probably want to call FB.api in a for loop iteration if this is the case you need its proper solution which exists in the use of Closures. Please read my answer here, given in another question

My solution was to make a recursive call until i got what i need from the FB.api

Related

Nested AJAX requests without a callback success function

After reading this thread jQuery Ajax Request inside Ajax Request
Hi everyone I need to have explanations about such a situation.
I've just been working on the code of a former member of my development team and found many parts of the code where he makes asynchronous ajax calls within other ajax calls.
My question is: can anyone explain the advantages and disadvantages of this practice and whether it is a good or bad practice?
Here is an example of code:
// first ajax (starting ajax call)
$.ajax({
url: "script1.php",
type: "POST",
data: {paramFisrtAjax: "first-ajax"},
success: function(response) {
alert(response);
}
});
script1.php
<script>
// second ajax
$.ajax({
url: "script2.php",
type: "POST",
data: {paramFirstAjax: "<?= $_POST['paramFisrtAjax'] ?>", paramSecondAjax: "second-ajax"},
success: function(response) {
alert(response);
}
});
</script>
<?php
// some operations on database server
echo "page2 operations with param: paramFirstAjax-> {$_POST['paramFirstAjax']}";
?>
script2.php
<?php
// some operations on database server
echo "page3 operations with params: firstParam -> {$_POST['paramFisrtAjax']} and secondParam-> {$_POST['paramSecondAjax']}";
?>
Something tells me it's not a good thing becouse i think the correct way is use the callback function success.
Like this: jquery nested ajax calls formatting
There is an advantage and a disadvantage here.
The Advantages are:
1) You make an async call, making the request a lot faster. You do not wait for the callback function, thus do not wait for your response which might take time to return. You do everything on the background rather then 'straight forward'.
This is understandable when you call multiple methods and you do not want the delay in waiting for the callback.
2) You are able to fetch a far greater amount data through your call while minimizing the need of the end client to wait.
This is useful when you have a big amount of data to display and you want to make it with minimal effort.
The Disadvantages:
1) Error handling is a pain. If something fails within the inner calls, it takes time to detect were the failure occurred and on which method.
When waiting for the callback, you can detect right away where the error occurred, as it will return a response of success or error,
2) if there is a mismatch on the data, it is hard to track back and see where the missing part took place, you will have to go through each request one by one to detect and use developer tools and/or fiddler as well, since those are async calls at the end.
3) it is easy to put too much effort on the client, since maintaining this kind of technique might result in calling multiple methods that will work together at the same time, thus creating overload on the client, locks on the threads or DB when working with server side code and more.
This explained, you can now decide for yourself with which type of method you would like to continue further in your code.

jquery ajax call synchronous for databases

I'm creating a web site using ASP. NET with a large client side that takes care of many events for the site. On the client side via AJAX I update, delete and add to the database (in that order!).
My question is, because the order of the tasks is very important: first- update database, second- delete from database, third- add to database:
Should I make the AJAX call synchronous? by changing "async" to false"?
or should I leave it as true by default?? which approach should I take?
U should do this by sending only one ajax call for all the operation you needed and make that ajax call async false.
In this case it would be better to instead use async: true and chain your requests so that they happen one after the other.
$.ajax({
type:'put',
url: '/model/7256185',
data: {name: 'Lucy'}
}).then(function () {
return $.ajax({
type:'delete',
url: '/model/7256186'
});
}).then(function () {
return $.post('/model', {name: 'bob'});
}).then(function (result) {
console.log("All Done!");
console.log(result);
}, function () {
console.log('An error has occurred!');
console.log(arguments);
});
This ensures that the requests happen in order, and it doesn't cause your page to appear broken during the requests (which is what happens with a synchronous request.)
It also allows you to use a loading gif if you so wish. With synchronous requests, loading gifs won't spin.
You DEFINITELY need to use transactions either at the business or at the data layer of your backend.
I usually prefer performing brief tasks (each entity with their own repositories) and keep the connection open for as little as possible in the Data Layer, then manage the transactional logic in the business layer using - for example - the TransactionScope class.
After this, it doesn't really matter whether you call the service/method in a sync or async fashion.

Is it okay to use async: false if calling for small data?

I'm mainly asking this to know what's the best practice with regards to getting small data from the server.
Like for one example, I'm using an ajax(or sjax. lol) call to check if there are new Notifications for a user
function checkNewNotifs() {
$.ajax({
url: '/Home/CheckNewNotifications',
async: false,
success: function (data) {
if (data == 'True') {
$('#alert-icon').css('color', '#FF4136');
}
}
})
}
It gets the job done, but I'm thinking if there's a better way of achieving this?
I'm mainly using ASP.NET MVC 4/5 as of the moment to provide context.
Edit:
For the future ajax beginner readers like myself, the proper way of achieving something similar to this is through .done() I haven't completely grasped the idea of ajax yet, but a lot can be done through the following call:
function checkNewNotifs() {
$.when(
$.ajax({
url: '/Home/CheckNewNotifications',
success: function (data) {
//do data manipulation and stuff.
}
})).done(function() {
//append to view
})
}
tl;dr async: false = bad
The main reason why you should avoid sync request**s is a **hang outs of UI.
Is there a reason why do you use sync requests?
I think you should use async requests to check notifications, because in case when request will take a bit more time than you expect - user will not see any freezing of UI.
Especially this problem will be actual for users with slow internet connection or slow connection to your server (different country, or event different continent).

Load .txt file using JQuery or Ajax

How can I fix the script below so that it will work EVERY TIME! Sometimes it works and sometimes it doesn't. Pro JQuery explains what causes this, but it doesn't talk about how to fix it. I am almost positive it has to do with the ajax ready state but I have no clue how to write it. The web shows about 99 different ways to write ajax and JQuery, its a bit overwhelming.
My goal is to create an HTML shell that can be filled with text from server based text files. For example: Let's say there is a text file on the server named AG and its contents is PF: PF-01, PF-02, PF-03, etc.. I want to pull this information and populate the HTML DOM before it is seen by the user. A was ##!#$*& golden with PHP, then found out my host has fopen() shut off. So here I am.
Thanks for you help.
JS - plantSeed.js
var pageExecute = {
fileContents:"Null",
pagePrefix:"Null",
slides:"Null",
init:function () {
$.ajax({
url: "./seeds/Ag.txt",
success: function (data){
pageExecute.fileContents = data;
}
});
}
};
HTML - HEAD
<script type="text/javascript">
pageExecute.init();
</script>
HTML - BODY
<script type="text/javascript"> alert(pageExecute.fileContents); </script>
Try this:
var pageExecute = {
fileContents:"Null",
pagePrefix:"Null",
slides:"Null",
init: function () {
$.ajax({
url: "./seeds/Ag.txt",
async: false,
success: function (data){
pageExecute.fileContents = data;
}
});
}
};
Try this:
HTML:
<div id="target"></div>
JavaScript:
$(function(){
$( "#target" ).load( "pathToYourFile" );
});
In my example, the div will be filled with the file contents. Take a look at jQuery .load() function.
The "pathToYourFile" cand be any resource that contains the data you want to be loaded. Take a look at the load method documentation for more information about how to use it.
Edit: Other examples to get the value to be manipulated
Using $.get() function:
$(function(){
$.get( "pathToYourFile", function( data ) {
var resourceContent = data; // can be a global variable too...
// process the content...
});
});
Using $.ajax() function:
$(function(){
$.ajax({
url: "pathToYourFile",
async: false, // asynchronous request? (synchronous requests are discouraged...)
cache: false, // with this, you can force the browser to not make cache of the retrieved data
dataType: "text", // jQuery will infer this, but you can set explicitly
success: function( data, textStatus, jqXHR ) {
var resourceContent = data; // can be a global variable too...
// process the content...
}
});
});
It is important to note that:
$(function(){
// code...
});
Is the same as:
$(document).ready(function(){
// code
});
And normally you need to use this syntax, since you would want that the DOM is ready to execute your JavaScript code.
Here's your issue:
You've got a script tag in the body, which is asking for the AJAX data.
Even if you were asking it to write the data to your shell, and not just spout it...
...that's your #1 issue.
Here's why:
AJAX is asynchronous.
Okay, we know that already, but what does that mean?
Well, it means that it's going to go to the server and ask for the file.
The server is going to go looking, and send it back. Then your computer is going to download the contents. When the contents are 100% downloaded, they'll be available to use.
...thing is...
Your program isn't waiting for that to happen.
It's telling the server to take its time, and in the meantime it's going to keep doing what it's doing, and it's not going to think about the contents again, until it gets a call from the server.
Well, browsers are really freakin' fast when it comes to rendering HTML.
Servers are really freakin' fast at serving static (plain-text/img/css/js) files, too.
So now you're in a race.
Which will happen first?
Will the server call back with the text, or will the browser hit the script tag that asks for the file contents?
Whichever one wins on that refresh is the one that will happen.
So how do you get around that?
Callbacks.
Callbacks are a different way of thinking.
In JavaScript, you perform a callback by giving the AJAX call a function to use, when the download is complete.
It'd be like calling somebody from a work-line, and saying: dial THIS extension to reach me, when you have an answer for me.
In jQuery, you'll use a parameter called "success" in the AJAX call.
Make success : function (data) { doSomething(data); } a part of that object that you're passing into the AJAX call.
When the file downloads, as soon as it downloads, jQuery will pass the results into the success function you gave it, which will do whatever it's made to do, or call whatever functions it was made to call.
Give it a try. It sure beats racing to see which downloads first.
I recommend not to use url: "./seeds/Ag.txt",, to target a file directly. Instead, use a server side script llike PHP to open the file and return the data, either in plane format or in JSON format.
You may find a tutorial to open files here: http://www.tizag.com/phpT/fileread.php

How to obtain jquery post return values?

I want to retrieve the height and width of an image on a server by using an ajax post call to a php file which returns a double pipe delimited string 'width||height'
My javascript is correctly alerting that requested string from the php file so the info is now in my script but i cannot seem to access it outside the $.post function.
This works:
var getImagesize = function(sFilename)
{
$.post("getImagesize.php", { filename: sFilename, time: "2pm" },
function(data){
alert(data.split('||'));
});
}
But retrieving is a different matter:
// this line calls the function in a loop through images:
var aOrgdimensions = getImagesize($(this, x).attr('src')) ;
alert(aOrgdimension);
// the called function now looks like this:
var getImagesize = function(sFilename)
{
var aImagedims = new Array();
$.post("getImagesize.php", { filename: sFilename },
function(data){
aImagedims = data.split('||');
});
return "here it is" + aImagedims ;
}
Anyone able to tell me what i'm doing wrong?
You are misunderstanding the way that an AJAX call works. The first "A" in AJAX stands for asynchronous, which means that a request is made independent of the code thread you are running. That is the reason that callbacks are so big when it comes to AJAX, as you don't know when something is done until it is done. Your code, in the meantime, happily continues on.
In your code, you are trying to assign a variable, aOrgdimensions a value that you will not know until the request is done. There are two solutions to this:
Modify your logic to reconcile the concept of callbacks and perform your actions once the request is done with.
Less preferably, make your request synchronous. This means the code and page will "hang" at the point of the request and only proceed once it is over. This is done by adding async: false to the jQuery options.
Thanx for the Asynchronous explaination. I did not realize that, but at least now i know why my vars aren't available.
Edit: Figured it out. Used the callback function as suggested, and all is well. :D

Categories

Resources