javascript function with parameters in function-call possible? - javascript

Does following call make sense / is it even possible?
getCall('GET', URL, null, function(x, status, jqXHR){ }, failedRes);
function getCall(method, url, data, func, func2){
.ajax({
type: method,
contentType: "application/json",
data: data,
url: url,
dataType: "json"
}).done(function(data, textStatus,jqXHR) {
console.log("done");
}).fail(function(jqXHR, textStatus, err){
console.log("fail");
});
}
function func2(jqXHR, textStatus, errorThrown){
window.alert("AJAX call error occured");
console.error( errorThrown );
}
I wonder most because of the "{}", but also because of the parameters.
Is the function-parameter "function(data, textStatus, jqXHR){ }" too much? Rather the {} not correct?

function(x, status, jqXHR){ } defines a function which can be called, but when it is called it doesn't do anything except returning undefined. In some situation, this might be intentional.
In this case I wonder why that parameter exists at all, because getCall doesn't even use the parameter func.

You can pass anything in. Personally, I like to set up data passing in a more structured manner just in case, in the future, things need to be updated. Passing function references or functions themselves is totally doable.
ala:
var data = {
call: "GET",
url: URL,
data: null,
func: function(x, status,jqXHR){},
func2: failedRes
}
getCall(data);
function getCall(data){
data = data || {};
// then just access your vars like so: data.url

Yes, this works.
function callFunction(func, param) {
return func(param);
}
callFunction(
function(a) {
return a*2;
},
2
);
returns 4

This is JavaScript AJAX request/response format:
function xhr(method, url, send, success){
var x = new XMLHttpRequest || new ActiveXObject('Microsoft.XMLHTTP');
var v = send ? encodeURI(send) : null;
method = method.toUpperCase();
x.open(method, url);
if(method.match(/^POST$/)){
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
x.setRequestHeader('Content-length', v.length); x.setRequestHeader('Connection', 'close');
}
x.onreadystatechange = function(){
if(x.readyState === 4 && x.status === 200){
success(x.responseText);
}
}
x.send(v);
}

Related

Working with two URLs in ajax

I have to get values from two different URLs and then to merge it. I know it would much better if i'll get all of the data in one URL, but that's how i've got and i need to work with it.
I want to print out the value of a_value, but it's been printed out while b hasn't returned his value. I've read some articles of how to make the functions synchronous but still don't know how to implement it into my code, and don't know what is the best solution for my case. I'm pretty new with JavaScript and still need some help and guiding.
function any_function() {
$.ajax(
{
url : '/url1',
type: "GET",
success:function(data, textStatus, jqXHR)
{
$("#print").html(a(data));
}
});
}
function a(data){
x = 'any value' //`do something with data and insert to this variable`
a_value = x + b(`some id that extracted from data`)
return a_value
}
function b(id){
$.ajax({
url: '/url2',
type: 'GET',
success: function (data, textStatus, jqXHR) {
b_value = c(data, id)
}
});
return b_value
}
function c(data, id){
//do something with `data` and return the value
return c_value
}
function f() {
var request1 = $.ajax({
url : '/url1',
type: 'GET'
});
var request2 = $.ajax({
url: '/url2',
type: 'GET'
});
$.when(request1, request2).done(function(result1, result2){
data1 = result1[0]
data2 = result2[0]
// r1 and r2 are arrays [ data, statusText, jqXHR ]
// Do stuff here with data1 and data2
// If you want to return use a callback or a promise
})
}
This can be done in a synchronous-looking fashion with promises:
$.get(url1)
.then(function(data1){
return $.get(url2)
})
.then(function(data2){
return $.get(url3);
})
.then(function(data3){
// All done
});
You just need to make the second call in the success handler of the first one:
function any_function() {
$.ajax({
url : '/url1',
type: "GET",
success:function(data, textStatus, jqXHR) {
$("#print").html(a(data));
b("someId");
}
});
}
function a(data){
x = 'any value' //`do something with data and insert to this variable`
a_value = x + b(`some id that extracted from data`)
return a_value;
}
function b(id){
$.ajax({
url: '/url2',
type: 'GET',
success: function (data, textStatus, jqXHR) {
b_value = c(data, id);
return b_value;
}
});
}
function c(data, id){
//do something with `data` and return the value
return c_value
}

Remake ajax function

Is there a way to make a function that converts default ajax function.
This is the ajax function i have
$.ajax({
type: "POST",
url: "http://" + document.location.host + '/userajax',
data: 'type=register&name=' + name,
beforeSend:function() {
},
success: function(response) {
}
});
This is what i want it to look like
ajax('url', {
method: 'get',
parameters: {
name: $('#name').val()
},
beforeSend: function() {
},
success: function(transport) {
}
});
Ive tried to search on the internet but did not find anything
Sure, you can create the function like this:
function ajax(url, params){
// everything is now available here
console.log( url ); // output: http://www.google.com
// you can get the data of the params object like this
console.log( params.method ); // output: get
// you can execute the beforeSend like this:
params.beforeSend();
// additionally you might want to check everything.
// maybe if the method is NOT set, you want it to always use GET
switch(arguments.length) {
case 1: url = throw new Error('Url should be set');
case 2: params.method = 'get';
case 3: break;
default: throw new Error('illegal argument count')
}
}
You would call this like:
ajax('http://www.google.com', {
method: 'get',
parameters: {
name: $('#name').val()
},
beforeSend: function() {
// some function
},
success: function(transport) {
// some function
}
});
This certainly is possible, it's just a bit of work. Some of the basics you need:
First of all, you need a good understanding of the XMLHTTPRequest API, you can find more info on that on MDN.
Next, finding out how to do a callback, that is actually quite simple, you can pass an anonymous function reference as an option or attribute for a function. That goes like this:
function doSomething(variable, callback){
variable = variable + ' something'; // just doing something with the variable
callback(variable);
}
// then call the function with a callback (anonymous function)
doSomething('doing', function(result){ alert(result); });
You should get an alert that says 'doing something'.
And finally you should know how to read an object, passed as 'options' in the ajax function. Say you have a function like this:
function foo(url, options){
console.log(url);
console.log(options.method);
console.log(options.parameters.name);
}
// call it like this
foo('https://google.com/', {
method: 'get',
parameters: {
name: 'myName'
}
});
That should log the url, method and parameters in the console.
Now from here, you should have all the pieces to put the puzzle together. Good luck!
I don't think so. but you can do this:
$(document).ready(function(){
var parameters = {
name: $("#name").val(),
desc: $("#desc").val()
};
$.ajax({
url: 'path/to/file',
data : parameters,
beforeSend: beforeSubmit,
dataType: "json",
type : 'POST',
})
.done(function(data) {
})
.fail(function() {
console.log("error");
})
})
Also note I don't set the function for the beforeSend directly in the call, I will create an externe function which gives me more freedom.
so I could do this:
function beforeSubmit(){
if(something !== 'somethingelse'){
return false; //ajax call will stop
}else{
return true; //ajax call
}
}

How to change javascript variable at appropriate scope based on success/failure of ajax get request

I want to edit a javascript variable based on whether or not a file exists. Can I achieve something like this?
var url="Content/Features/column1.html";
var url2="";
$.ajax({
url: url,
error: function()
{
url2 = "something";
},
success: function()
{
url2 = "something else";
}
});
My understanding is that the typical issue here is the async in ajax. Should I be using a callback method or a promise in some fashion?
Maybe something like:
var url="Content/Features/column1.html";
var url2="";
var result = $.ajax({
url: url,
error: function()
{
url2 = "something";
handleData(url2);
},
success: function()
{
url2 = "something else";
handleData(url2);
}
});
response = function handleData( responseData ) {
return responseData;
}
Or even:
var url="Content/Features/column1.html";
var url2="";
function test(url) {
return $.ajax(
{
url: url
}
);
}
test().done(function(url2) {
url2= "something"
}).fail(function() {
url2= "something else"
});
How can I change url2 at the same scope in which it was declared? Or is there a way to return a value from a callback function and change url2 based on that?
Alternatively, is there a better way to check if this file exists? (And before you tell me that browsers don't allow ajax requests to local files, please know that I am using node-webkit, not a browser)
None of these attempts worked quite right, but please let me know if I'm close. Thank you so much for your time.
Since AJAX is async in nature you cannot return a value from your function and instead need to implement a callback. You could do something like this:
function getURL2(callback) {
callback = callback || function() {};
var url="Content/Features/column1.html";
var url2="";
$.ajax({
url: url,
error: function()
{
callback("something");
},
success: function()
{
callback("something else");
}
});
}
getURL2(function(url2) {
// the call is complete and url2 is set correctly!
}
Try
var url1 = "Content/Features/column1.html"
, res = {"url2": void 0} // `this` `context` within `$.ajax` call at `request`
, request = function request(url1, res) {
return $.ajax({
context: res // set `this` to `res` object
, url: url1
, method: "GET"
, success: function(data, textStatus, jqxhr) {
this.url2 = "something"; // `success`
return this // return `this` : `res`
}
, error: function(jqxhr, textStatus, errorThrown) {
this.url2 = jqxhr.status === 404 // `404` , `Not Found`
? "somethingElse" // `error`
// if `error` other than `404`,
// return `jqxhr.status`
: jqxhr.status;
return this // return `this` : `res`
}
});
};
request(url1, res).always(function(response) {
// `this` : `res`
console.log(response.status
, response.statusText
, response.state()
, this.url2); // if `error` , `somethingElse` , else `something`
});
See jQuery.ajax( [settings ] ) at context , deferred.always()
var url1 = "https://gist.githubusercontent.com/anonymous/9a6997f09de9b68c59b2/"
+ "raw/f7d7b756005ad6d2b88cf0211f78a2990d7d2dc7" + "123" // `404` `error`
, res = {"url2":void 0}
, request = function request(url1, res) {
return $.ajax({
context: res
, url: url1
, method: "GET"
, success: function(data, textStatus, jqxhr) {
this.url2 = "something";
return this
}
, error: function(jqxhr, textStatus, errorThrown) {
this.url2 = jqxhr.status === 404
? "somethingElse"
: jqxhr.status;
return this
}
});
};
request(url1, res).always(function(response) {
console.log(response.status
, response.statusText
, response.state()
, this.url2);
document.write(JSON.stringify(this))
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

How can I pass a callback function into an $.ajax.done callback?

I'm calling a function, which makes an ajax GET to a url, like this:
// parameters = url, callback, boolean
that.mapUrl( window.location.search, function(spec) {
console.log("initial mapping done");
console.log(spec);
// do stuff
}, true);
mapUrl will trigger an Ajax request. Inside the Ajax done or success handler, I want to trigger my callback function, but doing it like this:
$.ajax({
method: 'GET',
url: obj[1],
context: $('body')
}).fail(function (jqXHR, textStatus, errorThrown) {
console.log("FAILED");
configuration = {
"errorThrown":errorThrown,
"textStatus": textStatus,
"jqXHR": jqXHR
}
}).done(function(value, textStatus, jqXHR) {
console.log("OK");
console.log(callback) // undefined!
configuration = {
"value":value,
"textStatus": textStatus,
"jqXHR": jqXHR
}
});
Question:
So I'm wondering how to pass my callback function into the ajax done-callback. Any idea how to do this?
Thanks!
EDIT
Here is the full mapURL function
that.mapUrl = function (spec, callback, internal) {
var key,
obj,
parsedJSON,
configuration = {"root" : window.location.href};
if (spec !== undefined && spec !== "") {
obj = spec.slice(1).split("=");
key = obj[0];
console.log(key);
switch (key) {
case "file":
$.ajax({
method: 'GET',
url: obj[1],
context: $('body')
}).fail(function (jqXHR, textStatus, errorThrown) {
console.log("FAILED");
configuration = {
"errorThrown":errorThrown,
"textStatus": textStatus,
"jqXHR": jqXHR
}
}).done(function(value, textStatus, jqXHR) {
console.log("OK");
configuration = {
"value":value,
"textStatus": textStatus,
"jqXHR": jqXHR
}
});
break;
default:
// type not allowed, ignore
configuration.src = [];
break;
}
}
return configuration;
};
It would be generally better to preserve the "promise" interface rather than passing callbacks into your code. This will allow you to better trap error conditions.
function mapUrl(url) {
return $.ajax(...)
.fail(...)
.then(function(data) {
// preprocess data and return it
});
}
where using .then you can manipulate the returned data before it's passed to the callback:
mapUrl(...).done(function(data) {
// data has been preprocessed
...
});
If the AJAX call fails, you can chain additional .fail handlers at this point too, which your current API would not permit. This "separation of concerns" would let you put nicer error handling UI in place, for example, without cluttering your AJAX code with UI-related code.

Creating a custom "sync" method in Backbone.js

Creating a custom sync() method in backbone.
I would like to do this the "right" and interfere with Backbone's normal functions as little as possible.
This is the code that I have so far:
var CustomSyncModel = Backbone.Model.extend({
sync:function(method, model, options){
var params = {
type: 'POST'
url: model.url(),
error: function(jqXHR, textStatus, errorThrown){
alert('error');
},
success: function(data, textStatus, jqXHR){
model.parse(data);
}
};
// Got this from line 1359 in Backbone.js developement library
// version 0.9.2:
$.ajax(_.extend(params, options));
}
});
The issue that I am having is that the line: $.ajax(_.extend(params, options)); seems to be overwriting the custom success and error functions that I created. But I'm also concerned about interfering with any custom callbacks or other functionality that may have been specified elsewhere in the application that is using this model.
What is the "correct" way to go about overriding the Backbone's sync() method?
Thanks!
If you look at Model#fetch you'll see the usual approach that Backbone uses:
fetch: function(options) {
//...
var success = options.success;
options.success = function(resp, status, xhr) {
if (!model.set(model.parse(resp, xhr), options)) return false;
if (success) success(model, resp);
};
//...
}
So Backbone just replaces the function with a new one that calls the original. In your case, you'd have something like this:
// We don't own options so we shouldn't modify it,
// but we can do whatever we want to a clone.
options = _(options).clone()
// Replace options.error with a wrapper.
var error = options.error;
options.error = function(jqXHR, textStatus, errorThrown) {
alert('error');
if(error)
error(jqXHR, textStatus, errorThrown);
};
// Replace options.success with a wrapper.
var success = options.success;
options.success = function(data, textStatus, jqXHR) {
model.parse(data);
if(success)
success(data, textStatus, jqXHR);
};
// We don't need error or success in here anymore.
var params = {
type: 'POST',
url: model.url()
};
$.ajax(_.extend(params, options));
BTW, your model.parse(data); in your success handler probably doesn't do anything useful, parse should just be a simple filter so you'd want to do something (such as a model.set call) with the model.parse(data) return value.

Categories