Error in Javascript return - javascript

I want to receive HTML code in chat.openChat() from chat.getHtmlPage() but return operation is "undefined".
var chat = {
openChat : function($url){
$('#popup').html(chat.getHtmlPage($url)); // It's wrong, UNDEFINED.
},
getHtmlPage : function($url){
$.ajax({
url: $url
}).done(function($html) {
return $html; // It's OK! $html is with correct html, see with alert().
});
}
}
$(document).ready(function(){
$('.btnChat').click(function(){
chat.openChat($(this).attr('href')); // It's OK!
...
return false;
});
});

By default AJAX request is asynchronous, so it ends after you get result from getHtmlPage. Even if you change it to be synchronous, you will still have undefined in openChat, because you return value from done handler, not from getHtmlPage.
You should provide a callback to getHtmlPage method. Example:
var chat = {
openChat : function($url){
chat.getHtmlPage($url, function(html) {
$('#popup').html(html);
});
},
getHtmlPage : function($url, callback){
$.ajax({
url: $url
}).done(callback);
}
}

Ajax calls are asynchronously, that's why you can't use the return of the ajax function immediately. to store the result in $('popup').
You will have to do something like this:
openChat : function($url){
chat.getHtmlPage($url));
},
setHtmlPage : function ($html) {
$('popup').html($html);
},
getHtmlPage : function($url){
$.ajax({
url: $url
}).done(function($html) {
chat.setHtmlPage($html);
});
}
You may also want to have a look to the jquery documentation about ajax. There is a way to make ajax requests synchronously, but that will block your browser and it's deprecated in the newer versions. (and it's not really ajax after all)
Check the part about async

It should be like this:
var chat = {
openChat : function($url){
chat.getHtmlPage($url);
},
getHtmlPage : function($url){
$.ajax({
url: $url
}).done(function($html) {
$('#popup').html($html);
});
}
}
$(document).ready(function(){
$('.btnChat').click(function(){
chat.openChat($(this).attr('href')); // It's OK!
...
return false;
});
});
AJAX is asynchronouse. Once you call it, script exection goes to next line and .done is called later, after request is finished. Also, return from done will do nothing. As it's jquery ajax event triggered after request is done. And jquery will not pass returned value to upper level of code even if you will make it work in synchronouse way.

The first 'A' in AJAX is 'Asynchronous', this means: by the time the .done() gets called, the rest of your code already moved on. With this knowledge, a return in .done() simply makes no sense.
Instead, we just deactiveate the asynchronous behaviour of AJAX, setting async: false in the .ajax-object. But be aware that this is not the original purpose of AJAX and it may cause trouble in some browsers.
Oone solution would then be to set the return into your getHtmlPage (in addtion to setting async to false!):
getHtmlPage : function($url){
//a new variable to store the ajax-result
//defining it here, so it's only visible within the scope of getHtmlPage
var html;
$.ajax({
url: $url,
async: false
}).done(function($html) {
//we use the html variable here to store the result
html = $html;
});
//finally returning the variable
return html;
}
This way, your return statement won't be executed until the ajax-call finishes.

SOLUTION
To do one general function (original idea).
var chat = {
openChat : function($url, $htmlElement){
chat.setHtmlPage($url, $htmlElement);
},
setHtmlPage : function($url, $htmlElement){
$.ajax({
url: $url
}).done(function($html) {
$($htmlElement).html($html);
});
}
}
$(document).ready(function(){
$('.btnChat').click(function(){
chat.openChat($(this).attr('href'), '#popup');
...
return false;
});
});

Related

how to execute one ajax function before the other using jquery

i am creating two ajax functions one in the traditional method and one with jquery. but when i do this the traditional method gets called first and in return i dont get some of my desired outcomes. how can i make the traditional ajax method to be translated into jquery?
here is my traditional ajax method:
function countFollowers() {
var xmlHttp = GetXmlHttpObject();
var url = "checkFollowers.php?username=" + document.followForm.follow_id.value;
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
var r = xmlHttp.responseText.trim();
if (r != "error") {
document.getElementById('followersCount').innerHTML = xmlHttp.responseText;
error = true;
return false;
}
}
}
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
if (error == true) {
return false;
}
}
here is my jquery ajax:
jQuery(document).ready(function($) {
$('.msg-icon').on('click', function(e) {
e.preventDefault(); //prevent a normal postback and allow ajax to run instead
var follow_id = $(this).find('input[name="follow_id"]').val();
$.ajax({
data: follow_id,
type: "post",
url: "followingsystem.php?follow=" + follow_id,
success: function(data) {
}
});
});
});
here is what i come up with so far to make the two ajax functions in the same on click function:
jQuery(document).ready(function($){
$('.msg-icon').on('click', function(e){
e.preventDefault(); //prevent a normal postback and allow ajax to run instead
var follow_id = $(this).find('input[name="follow_id"]').val();
$.ajax({
data: follow_id,
type: "post",
url: "followingsystem.php?follow="+follow_id,
success: function(data) {
}
});
$.ajax({
data: follow_id,
type: "post",
url: "checkFollowers.php?username="+follow_id,
success: function(data) {
}
});
});
});
but it is still not executing the response text that is coming from my php file
php code:
<?php
include("functions.php");
include("session.php");
require("connection.php");
if(isset($_GET['username'])){
$username =$_GET['username'];
$result= $db->prepare("SELECT * FROM users WHERE username=?");
$result->bindValue(1,$username);
$result->execute();
$row = $result->fetch();
if($result){
echo "Followers </br>". $row["followers_count"];
}
else{
echo "error";
}
}
?>
how will i get it to echo the $row["followers_count"] inside my span element?
You said in the comments you wanted to run the two requests sequentially instead of in parallel. Here's an all-round better way to organise your code which both allows that, and makes the code more re-usable, more maintainable and testable, and easier to understand in general.
I've used the Promise/Deferred interface provided by jQuery and AJAX as the way to chain the requests in sequence. Notice how each call is separated into each own function (so it's re-usable), but that function returns the Deferred object from the AJAX request, so you can use it to do something else when the request finishes.
Also based on your PHP I think the call to checkfollowers needs to be a GET (because PHP checks $_GET for the input value, and that's what your original XHR call was), and also you need to set the data with an explicit "username" parameter name so it'll be recognised.
It's not clear whether your call to followingsystem.php is correct or not because I can't see the PHP code for it.
jQuery(document).ready(function($) {
$('.msg-icon').on('click', function(e) {
e.preventDefault(); //prevent a normal postback and allow ajax to run instead
var follow_id = $(this).find('input[name="follow_id"]').val();
var request = follow(follow_id); //run the initial request, get back the Deferred object representing that request.
request.done(function() { //when the first request is done, run the second one.
checkFollowers(follow_id);
});
});
});
function follow(follow_id) {
return $.ajax({
data: { follow: follow_id},
type: "post",
url: "followingsystem.php?follow=" + follow_id
});
}
function checkFollowers(follow_id) {
return $.ajax({
data: { username: follow_id },
type: "get",
url: "checkFollowers.php",
success: function(data) {
document.getElementById('followersCount').innerHTML = data;
}
});
}

Show ajax process 1 by 1 when something is done

I have a code and it works, and it shows all notifications at the same time.
I have question..
How to get notifications when one of the functions is done? (Notifications appear one by one)
There are several functions in the indexing.php file.
$preproses = $_POST["preproses"];
if($preproses == "preproses"){
//mulai proses
set_time_limit(0);
buatindex();
hitungbobot();
panjangvektor();
}
function buatindex() {
code
}
function hitungbobot() {
code
}
function panjangvektor() {
code
}
In index.php there is a code to call that function
<script type="text/javascript">
function preproses(){
var preprosesx = "preproses";
$.ajax({
type : "POST",
url : "indexing.php",
data: {preproses:preprosesx},
error: function(){
$("#notif").prepend("fail");
},
success: function(html){
$("#notif").prepend("Process done <br/>"+html);
},
});
return false;
}
</script>
click to precess
If all processes are completed, a notification will appear
<span id="notif"></span>
$preproses = $_POST["preproses"];
if($preproses == "preproses"){
//mulai proses
set_time_limit(0);
setTimeout(function(){ buatindex() }, 3000);
setTimeout(function(){ hitungbobot() }, 3000);
setTimeout(function(){ panjangvektor() }, 3000);
console.log("Completed all");
}
function buatindex() {
code
}
function hitungbobot() {
code
}
function panjangvektor() {
code
}
Also you can console.log in ajax success response.
Something Like this : JsFiddle Example
count your post parameter ($_POST["preproses"]) and keep into an javascript variable like var count = ""; . you can also take an hidden text variable which will be increase by 1 after every notification send. after all notification values send this hidden variable will be equal to the count variable. then you can be sure that all the notifications have been sent. Hope this will work for you..:)
Haven't you tried async: false yet? This will stop further processing until one ajax request is complete.

Ajax request to check username

I am creating a signup form in HTML/CSS/JS which uses an AJAX request to get response from server. In my jQuery, I use a method to validate form contents which also calls a function (containing ajax) to see if the username exists or not. I have checked the similar questions but couldn't relate to my problem.
The AJAX goes inside a function like this
function checkIfUserNameAlreadyExists(username)
{
// false means ok, i.e. no similar uname exists
$.ajax
({
url : 'validateUsername.php',
type : 'POST',
data : {username:username},
success : function(data,status)
{
return data;
}
});
}
The PHP code looks like this
<?php
if($_SERVER['REQUEST_METHOD']=='POST')
{
$enteredLoop=false;
$linkobj = new mysqli('localhost','root','','alumni');
$query = "select username from user where username='".$uname."'";
$stmt = $linkobj->prepare($query);
$stmt->execute();
$stmt->bind_result($uname);
while($stmt->fetch())
$enteredLoop=true;
if($enteredLoop)
{
echo "
<script type='text/javascript'>
$('.unamestar').html('Sorry username already exists');
$('.userName').css('background-color','rgb(246, 71, 71)');
$('html,body').animate({
scrollTop: $('.userName').offset().top},
'slow');
</script>";
return;
}
}
?>
The function checkIfUserNameAlreadyExists returns false by default (don't know how) or this ajax request is not submitted, and it submits the form details to php.
Any help ?
Your checkIfUserNameAlreadyExists() function is synchronous and your ajax call is asynchronous. That means that your function will return a value (actually no value is returned at all in your case...) before the ajax call is finished.
The easiest way to solve this, is to generate the html in the success function, based on the return value of the data variable.
Something like:
success : function(data,status) {
if (data === 'some_error') {
// display your error message, set classes, etc.
} else {
// do something else?
}
}
Apart from that, are you actually setting the value of $uname to $_POST['username']?
You need to append response script to the document for executing.
function checkIfUserNameAlreadyExists(username)
{
// false means ok, i.e. no similar uname exists
$.ajax
({
url : 'validateUsername.php',
type : 'POST',
data : {username:username},
success : function(response)
{
$('body').append(response);
}
});
}

Calling Javascript Functions In Order

I'm trying to use a button to perform an API Call to Flickr, like so:
$(document).ready(function (){
$('#goButton').click(function (){
makeAPICall();
});
});
This works as expected, but the communication between the client and the Flickr API takes a while to execute, so the page appears like it is hung. I would like to add a "Working Notice" that is displayed immediately on button click to let the user know that their action is processing.
To do this, I added an H1 tag:
<h1 id="notice"></h1>
and a function that changes the inner HTML to display a notice:
function workingNotice() {
document.getElementById("notice").innerHTML="I am getting your results";
}
But when I try to edit the code for the button to something like this:
$(document).ready(function (){
$('#goButton').click(function (){
workingNotice();
makeAPICall();
});
})
The Working Notice is never displayed until the API Call has completed, which defeats the purpose.
I then tried using:
$(document).ready(function (){
$('#goButton').click(function (){
$.when(
workingNotice()
).then(
makeAPICall()
);
});
})
This gives the exact same results, where the Working Notice is not called until the API Call completes. Is there any alternative that I can try to force the order of these functions to comply?
UPDATE/EDIT:
While I found the solution to the initial problem in another answer, I know there's a reasonable chance the delay in the API Call processing is due to some mistake in this function. Here is the code for makeAPICall:
//call Flickr api and look for tags matching user search term
function makeAPICall(){
//get value tag from team 1 search box
var searchTag1 = escape(document.getElementById("searchTag1").value);
//get value tag from team 2 search box
var searchTag2 = escape(document.getElementById("searchTag2").value);
//build api call url with searchTag1
var url1 = "http://api.flickr.com/services/rest/?"
+ "method=flickr.photos.search&api_key=XXX&tags="
+ searchTag1 + "&sort=interestingness-desc"
+ "&safe_search=1&has_geo=1&format=json&nojsoncallback=1";
//build api call url with searchTag1
var url2 = "http://api.flickr.com/services/rest/?"
+ "method=flickr.photos.search&api_key=XXX&tags="
+ searchTag2 + "&sort=interestingness-desc"
+ "&safe_search=1&has_geo=1&format=json&nojsoncallback=1";
//make call to flickr api
$.when(
$.ajax({
dataType: "json",
url: url1,
async: false,
success : function(callReturn1) {
callData1 = callReturn1;
numResults1 = parseInt(callData1.photos.total);
}
}),
$.ajax({
dataType: "json",
url: url2,
async: false,
success : function(callReturn2) {
callData2 = callReturn2;
numResults2 = parseInt(callData2.photos.total);
}
})
).then(
drawChart()
);
}
Note "callData1", "callData2", "numResults1" & "numResults2" are all global.
If your makeAPICall is not async - call it out of bounds:
workingNotice();
setTimeout(makeAPICall, 1);

How to check if javascript function is ready/done (jQuery)

I am working on a learning planner which gets its data (languagekeys, tasks, activities, etc.) from a database. Because I need a JSON string, I encode it with json_encode to work with it in JavaScript.
I have a different function (for keys, tasks, activities, etc.) which gets this data and writes it into an array.
function get_tasks(start_date,end_date){
maxsubtasks=0;
maxtasks=0;
$.getJSON(json_data+"?t_startdate="+start_date+"&t_enddate="+end_date, function(data) {
tasks=new Array();
$.each(data.tasks, function(i,item){
tasks[i]= new Object();
tasks[i]["t_id"]=item.t_id;
tasks[i]["t_title"]=item.t_title;
tasks[i]["t_content"]=item.t_content;
. . .
if ( i > data.tasks.length) return false;
maxtasks = data.tasks.length;
if(item.t_parent > 0){
maxsubtasks++;
}
});
});
return true;
}
Everything is working just fine. I need some help, because I now have to call this function in $(document).ready(). I want to build my learning planner only once the function get_tasks() is complete (the array is filled with data). Otherwise, I will get errors.
How can this be solved?
Here is what I have in $(document).ready():
if(get_tasks(first_day,last_day) && get_tmp_data()){ // If this function is done
// This function should be fired -- just like a callback in jQuery
init_learnplanner();
}
You can add a callback to the function:
function get_tasks(start_date, end_date, callback) {
Then after populating the array in the function, call the callback function:
if (callback) callback();
Now you can use the callback parameter to initialise the learning planner:
get_tasks(first_day, last_day, function() {
init_learnplanner();
});
You should be able to specify a callback in $.getJSON, which gets executed as soon the request is completed.
EDIT:
You're already doing this, but why don't you just call the second code block from the end of the callback funciton in $.getJSON?
Other answers haven't worked for me because I have 5 functions which use my data with $.getJSON, and I need to have collected all information to even start init_learnplanner().
After several hours of searching, I've discovered the jQuery function ajaxComplete, which works like a charm for me. jQuery tracks all ajax calls that have been fired and triggers anything assigned .ajaxComplete() when one is complete.
What I'm doing is usually something like this:
simple, looks like beginner but it works :) :D
<script type="text/javascript">
var isBusy = true;
$(document).ready(function () {
// do your stuff here
isBusy = false;
});
function exampleajax() {
if(isBusy) return false;
isBusy=true;
$.ajax({
async: true,
type: 'POST',
url: "???.asp",
dataType: "jsonp",
data: qs,
error: function(xhr, ajaxOptions, thrownError){
//console.log(xhr.responseText + " AJAX - error() " + xhr.statusText + " - " + thrownError);
},
beforeSend: function(){
//console.log( "AJAX - beforeSend()" );
},
complete: function(){
//console.log( "AJAX - complete()" );
isBusy = false;
},
success: function(json){
//console.log("json");
}
});
}
</script>
hope this help you

Categories