How to convert beforeSend of ajax itno axios - javascript

I'm switching from ajax to axios, this is the code I wanted to convert.
$.ajax({
method: 'GET',
url: SPSConstants.SPS_BASE_URL + 'api/test?filter=' + encodeURIComponent(JSON.stringify(filter)),
dataType: 'json',
beforeSend: function (xhr) {
SPSUtils.getReqHeader(xhr, self, this, true);
},
}).done(function (result) {
var resultObj = JSON.parse(JSON.stringify(result));
let totalRecords = resultObj.pageInfo.total;
let currentPage = self.state.currentPage;
let currentRecords = resultObj.tollFreeNumberMasters;
if (totalRecords !== 0 && currentRecords.length === 0) {
self.setState({ currentPage: 1, pageInfo: { ...pageInfo, offset: 0 } }, () => {
self.loadTollFreeNumberTblData();
});
}
})
I've worked with axios earlier, so its not big of a deal. The only problem I'm facing is converting this part of ajax code into axios.
beforeSend: function (xhr) {
SPSUtils.getReqHeader(xhr, self, this, true);
},
is there any beforesend equivalent in axios?

It seems that you want to get the xhr object before the http request.
It is the Interceptors that functions similarly in the Axios.
axios.interceptors.request.use(config => {
console.log(config);
});
However, if you set the interceptors function on an Axios instance, the callback will work for all requests from that instance. To make callback work only for specific requests, you need to create and use a new instance of Axios.
const newAxios = axios.create();
newAxios.interceptors.request.use(config => {
console.log(config);
});

Related

How to send a POST request with Advanced Custom Fields data

I'm trying to send a post request to the rest api with some custom fields. THis is my code
let newCharacter = {
'title': $('.create-char-name').val(),
'acf': {
'char_class': $('#char-class').val(),
'char_subclass': $('#char-subclass').val(),
'char_level': $('#char-level').val()
},
'status': 'publish'
}
$.ajax({
beforeSend: (xhr) => {
xhr.setRequestHeader('X-WP-Nonce', spbk_data.nonce);
},
url: spbk_data.root_url + '/wp-json/wp/v2/character/',
method: 'POST',
data: newCharacter,
success: (response) => {
console.log("congrats");
console.log(response);
},
error: (response) => {
console.log("Sorry");
console.log(response);
}
});
The request goes through without any problems, but when I check the json, the "acf" field returns false.
I'm using the acf to wp api plugin, if that information is useful.
The only info I found about this issue was this post, but I don't really understand what the answer meant. I tried adding xhr.setRequestHeader('Content-Type', application/json); (I also tried with lower case initials), below the nonce, like the post seems to suggest, but that returns this error:
"{"code":"rest_invalid_json","message":"Invalid JSON body passed.","data":{"status":400,"json_error_code":4,"json_error_message":"Syntax error"}}"
Try something like below:
function NewCharacter(){
this.title;
this.acf;
this.status;
}
function CharInfo(){
this.char_class;
this.char_subclass;
this.char_level;
}
var charInfo = new CharInfo();
charInfo.char_class=$('#char-class').val();
charInfo.char_subclass=$('#char-subclass').val();
charInfo.char_level=$('#char-level').val();
var newCharacter = new NewCharacter();
newCharacter.title=$('.create-char-name').val();
newCharacter.acf=charInfo
newCharacter.status="publish";
$.ajax({
beforeSend: (xhr) => {
xhr.setRequestHeader('X-WP-Nonce', spbk_data.nonce);
},
url: spbk_data.root_url + '/wp-json/wp/v2/character/',
method: 'POST',
data: JSON.stringify(newCharacter),
success: (response) => {
console.log("congrats");
console.log(response);
},
error: (response) => {
console.log("Sorry");
console.log(response);
}
});
Yeah, I'm kinda dumb. I tried another plugin to make the bridge between acf and the rest api, and it worked.
It came to my mind many times to try another plugin, but I thought "they do the same thing, there's no point in trying that". It goes to show that you shouldn't just brush off solutions that seem too obvious or stupid.

Two requests in one time immediatly. ASP MVC + JQuery Ajax

MVC application (ASP.NET MVC, client: jquery).
Problem: The second ajax-request wait, when the first ajax request will done.
I need, when the first and the second ajax-requests executes immediatly in one time.
The page sends to server to determine the count of records (the first ajax-request), very long (~5-7 seconds).
The operator click the buttom to open the card to edit it (the second ajax-request, fast, get the Dto-model).
The user doesn't need to wait the first request, he wants to work immediatly.
As a result, in Chrome in network page, two requests in status 'pending'. The second waits the first.
Question, how can I send requests, to execute asynchronously ?
The first ajax-request:
`window.jQuery`.ajax({
type: 'POST',
url: Url.Action("GetCountBooks", "Book");
contentType: "application/json; charset=utf-8",
dataType: 'json',
data: JSON.stringify({ typeBook: "...", filter: "..." };),
success: function (data) {
// show in UI page the count of books by filter and params
},
error: function (data) {
//show error
}});
public class BookController : Controller
{
[HttpPost]
public NJsonResult GetCountBooks(string typeBook, Filter filter)
{
var data = DbProvider.GetCountBooks(typeBook, filter)
if (data.Result == ResultType.Success)
{
var count = data.Data;
return new NJsonResult
{
Data = new { Data = count }
};
}
return new NJsonResult
{
Data = new { Error = "Error while counting the books." }
};
}
}
The second ajax-request:
`window.jQuery`.ajax({
type: 'POST',
dataType: 'json',
contentType: "application/json",
url: Url.Action("GetBookById", "Book"),
data: JSON.stringify({ id: bookId }),
success: function (data) {
// show jquery dialog form to edit dto-model.
},
error: function (data) {
//show error
}});
public class BookController : Controller
{
[HttpPost]
public NJsonResult GetBookById(int id)
{
var data = DbProvider.GetBookById(id)
if (data.Result == ResultType.Success)
{
var book = data.Data;
return new NJsonResult
{
Data = new { Data = book }
};
return new NJsonResult
{
Data = new { Error = "The book is not found." }
};
}
return new NJsonResult
{
Data = new { Error = "Error while getting the book." }
};
}
}
I Cannot union ajax requests into one! The user can send various second request.
You need a fork-join splitter to fork 2 tasks and join based on some condition.
For example here is my implementation:
function fork(promises) {
return {
join: (callback) => {
let numOfTasks = promises.length;
let forkId = Math.ceil(Math.random() * 1000);
fork_join_map[forkId] = {
expected: numOfTasks,
current: 0
};
promises.forEach((p) => {
p.then((data) => {
fork_join_map[forkId].current++;
if (fork_join_map[forkId].expected === fork_join_map[forkId].current) {
if (callback) callback(data)
}
})
});
}
}}
Pass any number of async tasks (promises) into fork method and join when all are done. The done criteria here is managed by simple global object fork_join_map which tracks the results of your fork-join process (global is not good but its just an example). The particular fork-join is identified by forkId which is 0..1000 in this example which is not quite good again, but I hope you got the idea.
With jQuery you can create promise with $.when( $.ajax(..your ajax call) )
In the end you can join your promises like this
fork([
$.when( $.ajax(..your ajax call 1) ),
$.when( $.ajax(..your ajax call 2) )
]).join(() => {
// do your logic here when both calls are done
});
It's my own implementation, there may be already-written library functions for this in jQuery - I dont know. Hope this will give you a right direction at least.
The solution is to add attribute to Asp Controller: [SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
http://johnculviner.com/asp-net-concurrent-ajax-requests-and-session-state-blocking/

Many requests with final callback, unreliable order?

I'm trying to come up with a resource loader if you will, that will load many remote resources and then execute a final callback (like rendering a DOM based on the retrieve data from these requests).
Here's the function:
var ResourceLoader = function () {
this.requests = new Array();
this.FinalCallback;
this.Add = function (request) {
this.requests.push(request);
};
this.Execute = function() {
for (var x = 0; x < this.requests.length ; x++) {
var success = this.requests[x].success;
//if this is the last of the requests...
if (x == (this.requests.length - 1) && this.FinalCallback) {
$.when($.ajax({
url: this.requests[x].url,
dataType: 'json',
error: this.requests[x].error,
method: 'GET'
}).done(success)).then(this.FinalCallback);
}
else {
$.ajax({
url: this.requests[x].url,
dataType: 'json',
error: this.requests[x].error,
method: 'GET'
}).done(success);
}
}
};
};
And here's how I use it:
var apiUrl = Utilities.Api.GetWebApiUrl();
var loader = new Utilities.ResourceLoader();
loader.Add({
url: apiUrl + 'regions/get',
success: function (results) {
Filters.Regions = results;
}
});
loader.Add({
url: apiUrl + 'currentfactors/get/83167',
success: function (results) {
Filters.NbrEmployees = results;
}
});
loader.Add({
url: apiUrl + 'currentfactors/get/83095',
success: function (results) {
Filters.Industries = results;
}
});
loader.FinalCallback = RenderBody;
loader.Execute();
function RenderBody() {
console.log('render...');
}
Obviously, I'm expecting RenderBody to be executed last. But that's not what happening. What's ironic is that I remember doing something like that before, but lost the code... Looks like I'm having a brainfart here.
As you've tagged with promise - here's a really clean solution that uses Promise.all
this.Execute = function() {
Promise.all(this.requests.map(function(request) {
return $.ajax({
url: request.url,
dataType: 'json',
error: request.error,
method: 'GET'
}).done(request.success);
})).then(this.FinalCallback);
};
or ... using JQuery when
this.Execute = function() {
$.when.apply($, this.requests.map(function(request) {
return $.ajax({
url: request.url,
dataType: 'json',
error: request.error,
method: 'GET'
}).done(request.success);
})).then(this.FinalCallback);
};
Es6 Promise has solutions for your problem, there is no need to reinvent it unless the loading of resource groups is a specific goal to abstract. Set up a Promise object for each resource request, using the constructor to assign the resolve and reject callbacks appropriately for the XHR. Keep a collection (any Iterable will do) of individualPromise.then(individualCallback) results. Your final product is obtained by Promise.all(collectionOfPromises).then(finalCallback).

How to prevent sending duplicate request with a single click in AngularJs

I have an angularJs application that has an api call with a click on a link . but everytime i click on the link it sends 2 same api calls to the server. Why this occurs and how can i resolve this.
my service is like: SomethingService
function getData() {
return apiSettings.getApiInformation().then(function (response) {
var url = response.data.Url + "/odata/Something?$expand=Something";
var data = {
url: url,
type: "GET",
token: response.data.Token,
data: {},
async: true,
cache: false,
headers: {
"accept": "application/json; charset=utf-8",
'Authorization': 'Bearer ' + response.data.Token
},
dataType: "json",
success: {},
error: {},
complete: {},
fail:{}
};
return $http(data);
});
}
Api Settings :
angular.module('myApp.services')
.factory('apiSettings', apiSettings);
apiSettings.$inject = ['$http'];
function apiSettings($http) {
return {
getApiInformation: function () {
return $http.get(baseUrl+ '/api/GetApiInformation', {cache: true});
}
}
}
SomethingController:
var vm = this;
function getSlots(filterCriteria, selectedValue) {
somethingService.getData().then(function (response) {
if (response && response.value.length > 0) {
vm.someData = response.value;
}
});
View:
clicking on this link calls getSlots that sends duplicate request
<a ui-sref="something" class="action-icons" id="slotNav"><i class="fa fa-square-o fa-fw"></i>
something
</a>
this view displays data
<div ng-repeat="data in vm.someData">
<p> {{data.Name}}</p>
</div>
Issue: For a single trigger browser sends duplicate requests like the following. the first call doesn't have callback but the second call has callback:
someuls?$expand=something&_=1432722651197
someuls?$expand=something&_=1432722651197
I had a similar problem which I fixed by checking this answer. I had declared "ng-controller" in HTML as well as routed to it using routeProvider. Fixed the issue by removing the "ng-controller" property in HTML.
Hope this helps.

Issue in AJAX and JavaScript Object

I am trying to write a JavaScript Object which has many Properties and Methods. The basic function of this code is to send an ajax call and get data from server.
Code IS:
function restClient(options) {
var _response;
var _response_status;
var _response_message;
var _response_data;
// Default Options
var _default = {
restCall: true,
type: "GET",
url: '',
contentType: "application/json; charset=utf-8",
crossDomain: false,
cache: false,
dataType: 'json',
data: {},
beforeSend: _ajaxBeforeSend,
success: _ajaxSuccess,
error: _ajaxError,
complete: _ajaxComplete
};
// Extend default Options by User Options
var ajaxOptions = $.extend(_default, options);
// Private Methods
function _ajaxBeforeSend() {
}
function _ajaxSuccess(response) {
_response = response;
_response_status = response.status;
_response_message = response.message;
_response_data = response.data;
}
function _ajaxError(xhr, status, error) {
_response_status = xhr.status;
_response_message = error;
}
function _ajaxComplete(xhr, status) {
}
// Send Ajax Request
this.sendRequest = function() {
$.ajax(ajaxOptions);
};
// Get Server Response Pack [status,message,data]
this.getResponse = function() {
return _response;
};
// Get Server Response Status: 200, 400, 401 etc
this.getStatus = function() {
return _response_status;
};
// Get Server Message
this.getMessage = function() {
return _response_message;
};
// Get Server Return Data
this.getData = function() {
return _response_data;
};
}
Now I am trying to create object using new operator and call sendRequest(); method to send an ajax call and then I am calling getResponse(); to get server response like:
var REST = new restClient(options);
REST.sendRequest();
console.log(REST.getResponse());
Every thing is working properly But the problem is REST.getResponse(); call before to complete Ajax which give me empty result. If i do like this
$(document).ajaxComplete(function(){
console.log(REST.getResponse());
});
then it work But Still two problems are
If there are another ajax call its also wait for that
its looking bad I want to hide this ajaxComplete() some where within restClient();
Please Help me.
Thanks.
You have to change method sendRequest to accept a callback, that you'll call on response completion.
this.sendRequest = function(cb) {
this.cb = cb;
$.ajax(ajaxOptions);
};
this._ajaxComplete = function(xhr, status) {
this.cb && this.cb();
}
Also, after defining this._ajaxComplete change the _default.complete handler, in order to bind the this object, otherwise you'll miss the cb property:
_default.complete = this._ajaxComplete.bind(this);
Your client code will become:
var REST = new restClient(options);
REST.sendRequest(function(){
console.log(REST.getResponse());
});

Categories

Resources