I just have started writing AJAX functions using jquery. Here i am calling myfunction(). where check.php is returning {"count":1} or {"count":0} for which myfunction is always returning retval=false . But for {"count":1} it should return true. I dont know where i am wrong. Below is the code i am using.
function myfunction(){
var retval=false;
if($('#tag').val() != ''){
var query=$( "#tag" ).val();
$.getJSON("check.php",{
q: query
},function(data){
if(data.count==0){
$('#formerrormsg').html('Error msg');
}
else{
retval=true;
}
});
}
return retval;
}
Please Help me to understand this.
That is because, $.getJSON(..) is asynchronous. The below is what jQuery doc says about the third parameter you are passing (function(data){...}):
success(data, textStatus, jqXHR): A callback function that is executed if the request succeeds.
The function which set retval to true is executed when the AJAX call succeeds; not when you call myfunction()
There are two way you could get around this:
Make your AJAX call synchronous; the function wont return until the response is received. (Not a great idea, UI might freeze)
Modify your code -- the asynchronous way. Typically, call the function (that would ideally be depending on the return value) from within the "success-function" defined as the 3rd parameter.
It is an AJAX (asynchronous) request so return retval; is returning before the AJAX success function executes, hence always returns false. You need to change your implementation to wait for that request before returning and using retval.
Related
I do ajax request in foreach and question is that how to get request data in success callback or how to match response data and request.
Thank you in advance!
Something like this:
var makeRequest = function(data){
doAjaxRequest(data, function(dataFromServer){
console.log(data);
});
}
array.forEach(function(element){
makeRequest(element.getData());
}
What this does is for each element in array, the variable data is different because it refers to the local scope of the function makeRequest. This way, each callback refers to the proper data.
So I've done extensive research and read many tutorials but I can't find a straightforward answer to what I'm trying to accomplish.
I'm simply trying to access a JSON object stored at JSON-Generator.com and stick it in a table and repeat it. Sounds simple enough but it seems there many different ways to do this and all the sources leave out the one piece of info I need.
if I console.log eventsService inside the controller it returns a constructor, if I console.log eventsService.data it returns undefined.
How do I access the data returned from $http in my controller?
// CONTROLLERS
app.controller('currentTradeshowsController', ['$scope', 'eventsService', function($scope, eventsService){
$scope.events = eventsService.data;
}]);
// SERVICES
app.service('eventsService',function($http){
var eventsUrl = 'http://www.json-generator.com/j/bVWJaYaWoO?indent=4';
$http({method: 'GET', url: eventsUrl}).
success(function(data){
// not sure what to write here....
return data;
})
.error(function(){
console.log('ah shit');
})
});
first of all, $http call is asynchronous, so you probably want to use promises to load the data correctly into scope variable
second - you need to return something from the service to make it work outside of the service declaration function
controller
app.controller('currentTradeshowsController', function($scope, eventsService){
eventsService.getData().then(function(data) {
$scope.events = data;
});
});
service
app.service('eventsService',function($http){
var eventsUrl = 'http://www.json-generator.com/j/bVWJaYaWoO?indent=4';
return {
getData: function() {
return $http.get(eventsUrl);
}
}
});
$http.get is a shorthand for GET request, and it returns a promise, so you can simply use it with .then in the controller
I have this defined in controller
$scope.files = {};
Then I have a ajax call to get data and pass to $scope.files;
In the same controller. I have a ng-click function which I want to manipulate $scope.files
How to do that because it is async. I tried and the $scope.files always return blank {}
$scope.click = function() {
//Do something to $scope.files;
}
My fault. this is not related to async. I can actually get the data.
My problem is the return data is object and I tried to use .length to get the length of object so it always return 0 and {}. And I found .length for array.
and Object.keys(a) for object sizes
Looks like you need to use promise/deferred implementation. Promises allow you to execute code and once the promise is returned then continue.
Not sure if SFDebug is any help in this situation. I am making an ajax post using jQuery. Which retrieves JSON data in my action URL and then makes a call to the Model method that executes the action. The part until my action URL, and the jQuery call to it work fine. With the data transmitted from the client to the server well received and no errors being made.
It is the part where it calls the method on the Model that is failing. My jQuery method looks like this:
$.post(url, jsonData, function(servermsg) { console.log(servermsg); }) ;
My server action is like this
public function executeMyAjaxRequest(sfWebRequest $request)
{
if($request->isXmlHttpRequest())
{
// process whatever
$servermsg = Doctrine_Core::getTable('table')->addDataToTable($dataArray);
return $this->renderText($servermsg);
}
return false;
}
The method of concern in the Table.class.php file looks like this:
public function addDataToTable($dataArray)
{
// process $dataArray and retrieve the necessary data
$data = new Data();
$data->field = $dataArray['field'];
.
.
.
$data->save();
return $data->id ;
}
The method fails up here in the model, when renderText in the action is returned and logged into the console, it returns the HTMl for SFDEBUG. Which indicates that it failed.
If this was not an Ajax call, I could debug it by seeing what the model method spat out, but this is a little tedious with Ajax in the mix.
Not looking for exact answers here, but more on how I can approach debugging ajax requests in a symfony environment, so if there are suggestions on how I can debug this, that would be great.
You must send cookie with session ide key via ajax
(Assuming you have XDEBUG configured on the server)
In order to trigger a debug session by an AJAX request you have to somehow make that request to send additional URL parameter XDEBUG_SESSION_START=1. For your example:
$.post(url + '?XDEBUG_SESSION_START=1', jsonData, function(servermsg) { console.log(servermsg); }) ;
You can also trigger it via cookie, but appending URL parameter usually easier.
I have an action in my controller which does something only if the request is an XmlHttpRequest, like this:
function myAction() {
if( $this->request->is('ajax') ) {
doSomething();
}
}
What would a TestCase for this action look like? Is there a way to mock up the CakeRequest instance to appear as an Ajax request?
I don't know if it is a good way or not, but adding
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
at the top of the test method will do the job. In this case we send data as Ajax so not need to check any more.
we use a trick to solve ajax unit test for cake2.0
as cake supoprts .json extention, we create a function in AppModel to cheat ajax call. like
public function isAjax() {
return $this->request->isAjax() || $this->request->ext == 'json';
}
Then in controller, instead of calling $this->request->isAjax(), $this->isAjax() is used.
When testing action with ajax call, we simply add suffix .json to the action call, For example,
$this->testAction('/users/register');
This might not be the ultimate solution for ajax call test, but could be a workaround