Ajax json requests and responses - javascript

I'm hoping I can get some help understanding what's happening in this bit of code at a rather fundamental level.
I know that this is basically making a call to the specified URL. I also know that it should be returning a JSON object. If the call succeeds, then it calls my displayResults function, which I defined below.
The displayResults function takes a single parameter.
If I pass it a simple string for example ("response", in the code), everything works fine. However, I'd like to pass the response object from the API call as an argument to the function, but I cannot figure out how. Does the response object have a specific name I should be using?
$.ajax({
url: wikiAPI,
dataType: "json",
success: displayResults //dont call the function, pass it. it will be called when the response is ready.
});
function displayResults(data){
console.log(data);//here is your response
$(".results").html("<p><h3>Hello World!</h3></p>");
}

You have to understand that in Javascript, functions are "first-class", meaning that a function can be treated exactly as you would treat any other variable: you can pass it to another function as a variable, and return it from another function.
This is heavily used in javascript, especially as callbacks.
When you call the $.ajax function, you provide it an object as an argument. This object will contain the callback functions for different states of the ajax request -- one of which is success.
So, basically, the key success needs to have a value of type function.
Now, when you say displayResults("response"), you are calling the function displayResults with an argument "response" -- the return type of which is not a function.
If you just say displayResults without the (), you are treating the function exactly as you would do any other variable. The function is not executed.
You can do stuff like:
var functionAlias = displayResults;
Just like any other variable.
In the same way, you can do this:
$.ajax({
url: wikiAPI,
dataType: "json",
success: displayResults
});
Now, jquery will call the function you have provided when the ajax request has succeeded.
You can read the documentation for what arguments to expect in the function:
success
Type: Function( Anything data, String textStatus, jqXHR jqXHR
)
A function to be called if the request succeeds. The function gets
passed three arguments: The data returned from the server, formatted
according to the dataType parameter or the dataFilter callback
function, if specified; a string describing the status; and the jqXHR
(in jQuery 1.4.x, XMLHttpRequest) object.
So, your displayResults function will receive three arguments: data (can be of any type), textStatus (string), and jqXHR (XMLHttpRequest object). Although the argument names can be anything you want, it is common practice to keep it consistent with the docs.

about the success method parameter, it has no specific name it's dynamic take a look at this link JavaScript Object Methods
about your code,make your ajax call like below
$.ajax({
url: wikiAPI,
dataType: "json",
success: function(data){
displayResults(data)
},
error:function(erData):function{cosole.log(erData)}
});
It seemsdisplayResults method is not complete since it receive an object as input you should iterate through your object in your method like below
function displayResults(data){
console.log("Ajax success response data:", data);
$.each( data, function( key, value ) {
$(".results").append(data.YourProperty);
})
};
do note that I used error method to make sure ajax call succeeded if not the error method will be fired
Hope it hepls

Try with this
$.ajax({
url : wikiAPI,
dataType : "json",
success: function(response){
displayResults(response)
}
});
})
function displayResults(data){
console.log("Ajax success response data:", data);
$(".results").html("<p><h3>Hello World!</h3></p>");
}

Related

Request help understanding Ajax scope when using 'this' in reference to a JS class that the Ajax code is contained in

I have a django web project where the client invokes server-side python code to send data to a third-party service and receive a response using ajax. I have all the client side functionality bundled into a class because there are variables I need the ajax callback function to be able to access. I was hoping a class would help this scoping issue I seem to be having, but the function being called by my ajax code upon success has no idea what context it's in.
My server response contains a list of words I want to render to the screen. I have a wrapper class containing an unordered list object that I've made an instance of in my main class that contains my function that contains my ajax code and another function that the ajax calls upon success. In the success function in the class, I'm using this to refer to my list object I have defined in my main class. The function invoking the ajax says my list is defined, but the function being called by the ajax says it's undefined.
function MainClass(...){
/* Variable I'm trying to access from my ajax callback. */
this.wordlist = new UnorderedList();
this.onAjaxRequest(data){
console.log(this.wordlist); /* defined */
$.ajax({
type: "POST",
url: url,
data: {
csrfmiddlewaretoken: csrfToken,
data: data
},
success: this.onAjaxSuccess
});
}
this.onAjaxSuccess(words){
this.wordlist.updateList(words); /* undefined */
}
}
I have discovered through other posters that doing this: success: this.onAjaxSuccess(this) seems to work (it feels like type casting to me). My this.wordlist reference in onAjaxSuccess is now defined, but the parameter being passed in is no longer my server response, but now a reference of my MainClass. I understand it is literally passing the entire object because of (this), but how do I get my server response data doing that?
You can bind this function context to onAjaxSuccess in the function declaration itself.
function MainClass(){
/* Variable I'm trying to access from my ajax callback. */
this.wordlist = ['hi','buddy'];
this.onAjaxRequest = function(data){
console.log(this.wordlist, 'onAjaxRequest'); /* defined */
$.ajax({
type: "POST",
url: 'https://jsonplaceholder.typicode.com/posts',
data: {
csrfmiddlewaretoken: null,
data: data
},
success: this.onAjaxSuccess
});
}
this.onAjaxSuccess = (function(words){
console.log(this.wordlist, 'onAjaxSuccess'); /* defined */
}).bind(this);
}
var mainClass = new MainClass();
mainClass.onAjaxRequest();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You need to bind the function reference to the object, so that this will work correctly within it. Use:
success: this.ajaxSuccess.bind(this)
Or you can use an arrow function:
success: words => this.ajaxSuccess(this)

Passing parameters to a function in Ajax

I'm following a tutorial on using Ajax with JavaScript, and this was the code we're making:
$('document').ready(function(){
$.ajax({
url: "AwesomeText.html",
type: "GET",
datatype: "Html"
})
.done(Success)
});
function Success(result){
$("p").append(result);
}
I got how it worked but there is one thing that confused me. We made a Success function to append the requested HTML file to the paragraph in the page, and then we passed a parameter called result, so from what I understand I can name the parameter anything and pass it as an argument and it will work. I took out success and passed in x as an argument and it still worked..
so my question is how does JQuery know it should store the requested HTML document in this parameter we're creating in this function? what if I have other functions will Jquery store the requested file to every function in it's parameter? I don't get how JQuery knows.
Also, there is a .done function in there, is that the same function that's explained here:
https://api.jquery.com/deferred.done/
why is it called deferred?
Default .done() callbacks will have 3 arguments passed through so based on your need you can use any of them in your success function with your own name.
three arguments passed are data, textStatus ,jqXHR
so your success function's first argument would be the response of the ajax call,i.e data recieved from the server,
second argument would be the status and third argument would the the jqueryXmlHttpRequest object.
based on your need you can access these objects in the same order
When you pass url to ajax it basically fetches that url and returns whatever it got at that url, AwesomeText.html in your case
and then it sends the content of that url to success function as a first parameter
Documentation
success = Type: Function( Anything data, String textStatus, jqXHR jqXHR
)
deferred .done(fn) method makes calling some method after the method on which .done was called [You can say Promise ] which makes synchronous calls
You can check following question for understanding the promises and .done() method
jQuery deferreds and promises - .then() vs .done()
The .done method accepts a "success" function as input.
Success: Function( Anything data, String textStatus, jqXHR jqXHR )
A function to be called if the request succeeds. The function gets
passed three arguments: The data returned from the server, formatted
according to the dataType parameter or the dataFilter callback
function, if specified; a string describing the status; and the jqXHR
(in jQuery 1.4.x, XMLHttpRequest) object. As of jQuery 1.5, the
success setting can accept an array of functions. Each function will
be called in turn.
So, the first argument (call it whatever - data / result / x / etc) will contain the reply of the server.
Source: http://api.jquery.com/jquery.ajax/

Execute javascript function using jquery ajax that will change html, passing parameters at it and then execute another code

i would like to make an Ajax request like that:
function test(par1,par2) {
alert("add");
return(par1+par2);
}
$.ajax({
url: test,
dataType: "script",
data: 2,3,
success: function(data) {
alert(data);
}
});
I think that i am doing something wrong.
You need to call test, not reference it:
url: test("/mypath/", "somelocation.php")
The difference is in the brackets, and provided arguments. Without brackets you pass a function reference without executing it. This does not resolve to the executed value. With brackets you execute the function and pass to the url property the return value, which is what you want.
Of course, you need to decide what you pass to the function. In your case, you might have them in some variables.
Secondly, you need to change the value passed to data as well. It should be an object where each property corresponds to a parameter name:
data: {par1: 2, par2: 3}
jQuery will do the translation to the url format.
I have the impression your test function was intended to add parameters to the url, but since the data property is intended for that, you probably can do away with that function. Just assign the basic url to the url property, without parameters:
url: "/mypath/mypage.php"

How to store $.getJSON object in global variable and navigate through it later

I'm experimenting with JQuery and trying to create a function to get dynamic data from a JSON returned API and store it in a global variable (I don't know if this is the right/best way to do this).
What I have so far is
function getdata(url){
var data = $.ajax({
type: 'GET',
url: url
});
return data;
};
So far everything works fine, but this returns an object with a "responseJSON" key and I can't seem to find a way to navigate to this key and then do a $.each loop through the arrays in it.
So the questions are:
Is this the right / way ( if not please explain your answer)
How do you navigate through a multidimensional object containing arrays in the "responseJSON" key.
Another approach is to pass a callback to your function so you can set the response handler within the function and less code when you call your getData method
function getdata(url, callback){
var data = $.ajax({
type: 'GET',
url: url
}).done(callback).error(function(){
alert('Oppps...something went wrong')
});
return data;
};
getData('urlstring', function(data){
/* doSomething with data */
})
AJAX is asynchronous. That means it runs in the background while the rest of your script runs. At a point in the future when the AJAX call completes, then you can access it.
In jQuery, $.ajax returns a promise. So what you can do is the following:
getdata('/path/to/your.json').done(function(data){
// Use your JSON data here
console.log(data);
});
What happens is that once the AJAX call is done, your .done() function will run and you will have access to the data returned.
Don't try to access the properties of the $.ajax object (the responseJSON won't be populated until the call is finished). Use callbacks to get at the returned data.
If you want the json data to be in global scope, just define a global variable (that is, outside the function), and then in the function fill it with the returned data. Something like so:
var api_response;
function get_data(url) {
$.post(url, function(j) { api_response = j; }, "json");
// or
$.getJSON(url, function(j) { api_response = j; });
}
You don't even need to create a function for this and can use jquery's own $.getJSON (the or case).

Javascript - local scope objects not accessible from nested function

I am trying to have a function grab an object from a php file on another page. I'm using the jQuery ajax function to to do the json grab, which is working correctly. The issue is when I try to return that object from the function.
The first time I log the object (from within the success function) it is correct in the console, but the returned object from the function getGantt() logs as "undefined".
How do I get this object out of the function?
My code:
function getGantt(requestNumber){
var ganttObject;
$.ajax({
type: "POST",
url: "get_gantt.php",
data: {request_number: requestNumber},
success: function(returnValue){
ganttObject = $.parseJSON(returnValue);
console.log(ganttObject); //this logs a correct object in the console
}
});
return ganttObject;
}
$(function(){ //document ready function
var requestNumber = $('#request_number').text();
var ganttObject = getGantt(requestNumber);
console.log(ganttObject); //this logs "undefined"
}); //end document ready function
The A in Ajax is an important part of the acronym. Asynchronous JavaScript and XML is asynchronous.
$.ajax({success:someFunction}) means Make an HTTP request and when the response arrives, run someFunction
return ganttObject runs before the response arrives.
You should do anything you want to do with the data inside someFunction and not try to return data to the calling function.
The A in AJAX stands for asynchronous. So the call immediately returns and as soon as it finishes, the success callback is called.
So, simply change your code to use a callback:
function getGantt(requestNumber, callback) {
var ganttObject;
$.ajax({
type: "POST",
dataType: 'json',
url: "get_gantt.php",
data: {request_number: requestNumber},
success: function(returnValue){
callback(returnValue);
}
});
}
$(function() {
var requestNumber = $('#request_number').text();
var ganttObject = getGantt(requestNumber, function(ganttObject) {
console.log(ganttObject);
});
});
Btw, I've also removed this parseJSON stuff - setting dataType to json does the job and is less dirty.
I know why it's not returning it at least. The ganttObject may be in the same scope, but the success function is ultimately running in the readyState callback from the XMLHTTP object, so it's on a different thread than the getGantt function. Can you make the $(function(){... code apart of your success function?

Categories