How to pass additional parameter to $http callback in following format - javascript

To keep my code concise and modular, I am using following way of processing HTTP calls.
From controllers I do:
function makeCall(){
Service.getDetails( url, obj).then(responseFn, errorFn);
}
In Service I do:
this.getDetails = function(url, obj){
return $http.get(url);
}
Then in Controller I have:
function responseFn(){
//response objct available here by deafult
}
function errorFn(){
//error objct available here by deafult
}
In these function I automatically get response and error object. In one case it is fine since I need only the response of GET but in one another case I ma calling same method from a different controller, and there I need to use a condition to manipulate the response.
Query: How do I pass a parameter i.e. 'obj' to these callback function from my original makeCall function. If I pass two dummy variables to callback function it do not work. (I expected first argument to be replaced by response and second argument as my argument)

One of your options is extend your returning object, in this case you will have a data access across the controller.
in your service:
this.getDetails = function(url, obj){
this.myObjData = obj; // bind it to your returing object
return $http.get(url);
}
in your controller:
function makeCall(){
Service.getDetails(url, obj).then(responseFn, errorFn); // respond parameter will attach by default, no need to bind it here
}
function responseFn(respond){
console.log(respond); // will attach by default
console.log(Service.myObjData); // access your data from here
}
Hope it help you.

Related

Exception when calling a self-executing function in an object literal

I'm trying to set a field's value to a function, then execute it. this.fetchLocalStorage is not a function is what I get from running it.
var app = {
busdata: (function(){return this.fetchLocalStorage()})(),
fetchLocalStorage: function() {
//fetching
return "fetching data...";
}
};
console.log(app.busdata);
Note that by not making it a self-executing function, it works, but then it would mean the function is called everytime when I only need to fetch the data one time.
busdata: function(){return this.fetchLocalStorage()}
/* ... */
console.log(app.busdata()); //this calls the function every time :(
Thought it might a context problem so I tried a couple things with bind and call but with no luck.
Am I missing something?
this is only bound to the object when you call a method of the object, i.e. app.someMethod(). But you're trying to call fetchLocalStorage() when you're creating the object, not in a method of the object, so this is whatever the outer context is, which is likely the global window object.
You can't refer to other properties of the object until after the object has been created. So just call the function normally after you create the object.
var app = {
fetchLocalStorage: function() {
//fetching
return "fetching data...";
}
};
app.busdata = app.fetchLocalStorage();
I think your params were on the wrong side of the brace.
busdata: (function(){return this.fetchLocalStorage()}() ),

How does javascript function call work?

I have this piece of code below:
It makes a GET call to an URL, gets some object, and appends an image to an HTML tag.
function getDataFromApi(searchTerm, callback) {
const URL1 = `some url`;
const design = {
url: URL1,
data: {
"dog breed name": searchTerm
},
type: 'GET',
success: callback
};
$.ajax(design);
}
function displaySearchData(data) {
const allResultsLength = data.message.length;
const ranNum = Math.floor(Math.random() * allResultsLength);
const dogResults = data.message[ranNum];
$(`.js-search-results`).html(`<img src = ${dogResults}>`);
}
function watchSubmit() {
$('.js-search-form').submit(event => {
event.preventDefault();
let queryTarget = $(event.currentTarget).find('.js-query');
let query = queryTarget.val();
queryTarget.val("");
getDataFromApi(query, displaySearchData);
});
}
$(watchSubmit);
I get the getDataFromApi and watchSubmit but getDataFromApi(query, displaySearchData); isn't intuitive to me at all.
I've been writing Java, and it doesn't make sense to me how displaySearchData is getting called without the parameter - it seems that line should be getDataFromApi(query, displaySearchData(data));.
Can someone please explain how this is getting compiled & executed (basically how this is a legitimate syntax) in javascript?
Somewhere in the good'ol jquery, there lies this piece of code:
$.ajax = function(config){
...
// get the response from XHR request,
// and save it in, say, 'response'
...
// now check, if the response is OK 200
// and if so, execute next line
// which is basically - calling your displaySearchData method
config.success(response);
...
}
now, config is your design object, which has a property success which carries the reference to your displaySearchData method.
The data argument of method displaySearchData will now carry the reference to variable response passed in the method invocation config.success(response).
EDIT: the argument callback also carries forward the reference of the method displaySearchData to getDataFromApi
Concept to be noted:
functions can be passed in Javascript as arguments to another function, in which case we only need the referring variable to be passed as argument. Invocation parentheses () are not required.
function A(data){...};
function b(referenceToFunctionA){
...
referenceToFunctionA(someData);
...
};
// correct
b(A);
// wrong, because adding () after any function reference variable
// invokes the method immediately.
// in this particular case the returned value of the method A
// is passed as argument instead of the reference to method A itself.
b(A());
Welcome to JavaScript My Friend. Get ready to experience more magical weirdness as you continue to work on JS. Good luck.
What you need to look at is in the function getDataFromApi().
In that function, you have a "callback" parameter. This parameter is later added into $.ajax. This is a jQuery function that will provide some callback when a certain condition is matched (like before sending a request, when the response has been received,...). This $.ajax callback provide you with 3 parameters, one of them is data (which are being used, textStatus, and jqXHR. Usually, you only need to pay attention to the data since it contains the response from where you are requesting data.
So when the $.ajax success, the "callback" function will be called, which is the displaySearchData. And since $.ajax callback provides you with the data parameter, you can add them to the parameters of displaySearchData. Do note that you can add the extra 2 provided parameters if needed.
You can have a look at that function here: jQuery Ajax

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).

Declare a javascript object. Then set properties with jQuery and Ajax

I can't access the attribute of an instantiated class. The attribute is set using an AJAX call.
I am trying to define the class "CurrentUser", and then set the attribute "userId" using AJAX.
Here I define the class CurrentUser, and give it the attribute userID:
function CurrentUser() {
// Do an ajax call to the server and get session data.
$.get("../../build/ajaxes/account/get_user_object_data.php", function(data) {
this.userId = data.userId;
console.log(data.userId); // This will correctly output "1".
}, "JSON");
}
Here I instantiate a CurrentUser named billybob. Notice how I can't output billybob's attribute:
// Instantiate the user.
var billybob = new CurrentUser();
console.log(billybob.userId); // This will incorrectly ouput "undefined".
I've checked the common errors with AJAX:
The AJAX call returns the data correctly as a JSON object. I can read the correct object in Firebug / Network console. The AJAX call also has a status of "200" and "OK".
I can log the AJAX call's data correctly, as seen in the first part of my code where I log data.userId.
Maybe this clears it out:
In your original code:
function CurrentUser() {
// Do an ajax call to the server and get session data.
$.get("../../build/ajaxes/account/get_user_object_data.php", function(data) {
this.userId = data.userId;
console.log(data.userId); // This will correctly output "1".
}, "JSON");
}
You are creating an anonymous function on the fly, that will be later called by jQuery's internals with this
set to an ajax object. So this will be the ajax object inside the anonymous function, not billybob. So when
you do this.userId = ... this means the ajax object which doesn't have a userid property.
jQuery will have no idea where you got your callback function from, so it cannot set the this automagically
for you.
What you must do is to save the billybob (or any CurrentUser instance) reference and use it in the callback like so:
function CurrentUser() {
var self = this;
$.get("../../build/ajaxes/account/get_user_object_data.php", function(data) {
self.userId = data.userId; //self refers to what this refered to earlier. I.E. billybob.
console.log(data.userId, self.userid); // This will correctly output "1".
}, "JSON");
}
Also note that:
var billybob = new CurrentUser();
console.log(billybob.userId);
By the time you call console.log (I.E. instantly after creating billybob), the ajax request hasn't been completed yet so it is undefined.
In constructor, consider doing
var self = this;
and in function
self.userId = data.userId;
this inside function will be different than outside. Although, I don't know JQuery. May be it's supposed to set up closure automatically.

How can we pass multiple parameters to onSuccess method of PageMethod?

I'm calling PageMethod "SameMethod" from javascript method "caller" so that I can get some values from DB. After I get values, control is continuing in "onSuccess" method. Problem is that I need to use some variable values ("importantValue") from javascript method "caller" in "onSuccess" method.
function caller(){
var importantValue = 1984;
PageMethod.SomeMethod(param1,..., onSuccess, onFailure)
}
onSuccess method should be something like this:
function onSuccess(pageMethodReturnValue, importantValue ){
}
Is it possible and, if it is, how to pass multiple parameters (besides return values of page method) to "onSuccess" method of PageMethod?
Thanks for help
Pass your importantValue as an additional parameter when calling the PageMethod. (this is usually called the context parameter if you are searching online for more info)
function caller(){
var importantValue = 1984;
PageMethod.SomeMethod(param1,..., onSuccess, onFailure, importantValue)
}
Then you can access the value in the onSuccess callback as follows:
function onSuccess(pageMethodReturnValue, context, methodName){
// context == 1984
}
Update to explain onSuccess parameters for #JacksonLopes
There is a good description on the aspalliance website in an article by Suresh Kumar Goudampally
The important bit (modified to use my parameter names) is:
The success call back method has three parameters:
pageMethodReturnValue - Returns the output of the page method.
context - This is used to handle different logic when single callback is used for multiple page method requests. We can also pass
an array of values as the context parameter.
methodName - This parameter returns the name of page method called.
You could use an anonymous function
PageMethod.SomeMethod(param1,..., function(){onSuccess(foo, importantValue)}, onFailure)

Categories