Not sure what I'm missing here. The console.log prints the correct data, but the return statement is not setting the values to my redux store.
// reducer.js
function getPreviousMonthData(state) {
$.ajax({
url: uri,
method: "GET",
dataType: "json",
success: (data) => {
const newObj = {
previousMonthTotal: data.totals[0],
previousMonth: data.app_reports
};
console.log(newObj);
return Object.assign({}, state, newObj);
}
});
}
In every other context of my app, return Object.assign({}, state, newObj); successfully sets data to my redux store, e.g.:
// reducer.js
function setState(state, newState) {
return Object.assign({}, state, newState);
}
function setToStore(state, data, label) {
let newObj = {};
newObj[label] = data;
return Object.assign({}, state, newObj);
}
EDIT: this is the reducer side of the action... my action-creator is a little bit wacky. The fuller story is that this ajax call comes at the end of a chain of dispatched actions that began with a different ajax call. The overall goal is to (1) receive one set of data based upon a range given by two unix time stamps; (2) calculate the prior month's range; and (3) take that new date range to create a new get request for the prior month's data. Everything works except for the final assignment of the prior month's data to the redux store.
// action_creators.js
export function getDataPointQuery(queryObj) {
const app = queryObj.app_id ? queryObj.app_id : CONFIG.test_app;
const token = queryObj.token ? queryObj.token : CONFIG.token;
const start_date = queryObj.start_date ? queryObj.start_date : CONFIG.start_date;
const end_date = queryObj.end_date ? queryObj.end_date : CONFIG.end_date;
const uri = CONFIG.host2+"/v3/apps/"+app+"/app_reports?token="+token+"&start="+queryObj.start_date+"&end="+queryObj.end_date;
return(dispatch) => {
$.ajax({
url: uri,
method: "GET",
dataType: "json",
}).then((data) => {
dispatch(setToStore(app, "appId"));
dispatch(setToStore(token, "token"));
dispatch(setToStore(data.app_reports, "dataQueryPeriod"));
dispatch(setToStore(data.totals[0], "dataQueryPeriodTotal"));
dispatch(setToStore(data.app_reports[0].created_at, "startDate"));
dispatch(setToStore(data.app_reports[data.app_reports.length-1].created_at, "endDate"));
}).then(() => {
dispatch(getPreviousMonthDates());
dispatch(createChartJsData());
}).then(() => {
dispatch(getPreviousMonthData());
});
};
}
Essentially, the final dispatch is failing to work as anticipated. I'm also cognizant of the fact that it is extraordinarily inelegant to make one ajax call from action_creators and another ajax call from reducer. I was hoping to get it working once and then refactor.
Following the advice from guruPitka, I ditched the reducer ajax call and implemented it into the action_creator, which created the following behemoth:
export function getDataPointQuery(queryObj) {
// variables and stuff
return(dispatch) => {
$.ajax({
url: uri,
method: "GET",
dataType: "json"
}).then((data) => {
dispatch(setToStore(app, "appId"));
dispatch(setToStore(token, "token"));
dispatch(setToStore(data.app_reports, "dataQueryPeriod"));
dispatch(setToStore(data.totals[0], "dataQueryPeriodTotal"));
dispatch(getMonthDates());
}).then(() => {
dispatch(getPreviousMonthDates());
dispatch(createChartJsData());
}).then(() => {
$.ajax({
url: previousUri,
method: "GET",
dataType: "json"
}).then((result) => {
console.log(result);
dispatch(setToStore(result.app_reports, "previousMonth"));
dispatch(setToStore(result.totals[0], "previousMonthTotal"));
});
});
};
}
Related
I would to avoid nesting a bunch of ajax calls inside the 'success' event of one another. I was wondering if someone could guide me in the right direction on how to do something like this? Where one ajax call is dependent on another's return value?
The getLoginAccess() function will be used in many other methods in a similar manner.
If the first one fails i would like to just have it return a 'null' value which i can then take into account before running the second ajax call. Below i demonstrate a psuedo example of what im trying to do.
The method getLoginAccess returns a dictionary of data that is required for the second method createItem to execute. So only if getLoginAccess returns valid data will createItem continue on to call the actual ajax call.
Thank you
function getLoginAccess() {
$.ajax({
url: '.../api/v1/auth/access_token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
'Connection': 'keep-alive'
},
data: {
grant_type: 'client_credentials',
username: 'johnDoe',
password: '******'
},
success: function (data) {
console.log(JSON.stringify(data));
return data;
},
error: function (data) {
console.log(data);
return null;
}
})
}
function createItem() {
var login = getLoginAccess();
if (login == null) {
return false;
}
$.ajax({
url: '.../api/v1',
method: 'POST',
headers = {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'access': `${login.access_token}`
};
data: {},
success: function (data) {
console.log(JSON.stringify(data));
},
error: function (data) {
console.log(data);
}
})
}
window.onload = function(){
createItem();
};
If you want to refactor the part where the login is verified we could create an intermediate function .. something like this:
Your login function here
function getLoginAccess(){
// Return login data or null
}
Here we can create an intermediate function to deal with the dependencies of the next execution. If the login returns something other than null, the function passed as a parameter will be executed.
function intermediateFunction(functionName,login){
if(login){
window[functionName]();
}
}
Here are the other functions you have created.
function createItem() {
// Do something
}
function listItem() {
// Do something
}
Here instead of calling the createItem() function you call the intermediary
window.onload = function(){
intermediateFunction(getLoginAccess(), "createItem");
};
So basically you would always call the intermediate function that would check the login before calling a particular function. I believe that this is how I would refactor :)
I have a problems sending information from a Laravel controller to TypeScript (TS)
I have tried using Ajax but I have not been able to get the information sent from controller
Laravel controller
public function getUrl()
{
$Id = request('id');
$urlAdjunto = Adjunto::where('articulo_id', $Id)->plunk('url');
return response()->json(['url' => $urlAdjunto]);
}
Ajax function in typescript
function getUrl(id) {
var a= $.ajax({
type : 'GET',
dataType: 'json',
url : '/adjunto',
data : {id}
});
return a;
}
A few small modifications to make this type safe and return a promise as expected:
async function getUrl(id: number): Promise<any> {
return await $.ajax({
type: 'get',
dataType: 'json',
url: '/adjunto',
data: {id}
})
}
And now you have a promise to work with that you can observe and react to in your code:
getUrl(15)
.then((response: any) => {
//response.data has everything you need
}).catch((error: any) => {
// do something with failures
})
Or call it from another async function and leverage await for cleaner syntax:
async myFunc(){
try {
const { data } = await getUrl(15)
// do something with your data
} catch(error) {
// we all make mistakes
}
}
I have been trying to load return a JsonResults action from a controller in MVC using ajax call. I can see that the alert() function is triggering well but the ajax is not executing. I have search for several sources but to no avail.
public JsonResult FillBusinessLicenceL3(int? selectedID)
{
var bl3_Items = db.LevelThreeItems.Where(l3 => l3.LevelTwoItem_ID == selectedID);
return Json(bl3_Items, JsonRequestBehavior.AllowGet);
}
The below too is the javascript calling for the json method.
<script>
function FillBussLicence_L3items() {
alert("You have clicked me");
var bl2_Id = $('#BussLicenceL2_ID').val();
//alert(document.getElementById("BussLicenceL2_ID").value);
alert(bl2_Id);
$.ajax({
url: 'StartSurvey/FillBusinessLicenceL3/' + bl2_Id,
type: "GET",
dataType: "JSON",
data: "{}", // { selectedID : bl2_Id },
//contentType: 'application/json; charset=utf-8',
success: function (bussLicence_L3items) {
$("#BussLicenceL3_ID").html(""); // clear before appending new list
$.each(bussLicence_L3items, function (i, licenceL3) {
$("#BussLicenceL3_ID").append(
$('<option></option>').val(licenceL3.LevelThreeItem_ID).html(licenceL3.LevelThreeItem_Name));
});
}
});
}
Also, I have tried this one too but no execution notice.
Thanks a lot for your help in advance.
After looking through the browser's console, I noticed that the LINQ query was tracking the database and was creating a circular reference so I changed the query to the following and voila!!
public JsonResult FillBusinessLicenceL3(int? selectedID)
{
var bl3_Items = db.LevelThreeItems.
Where(k => k.LevelTwoItem_ID == selectedID).
Select(s => new { LevelThreeItem_ID = s.LevelThreeItem_ID, LevelThreeItem_Name = s.LevelThreeItem_Name });
return Json(bl3_Items, JsonRequestBehavior.AllowGet);
}
There was nothing wrong with the ajax call to the controller.
I have a function called getStudentData(),returns resolved data.
Inside getStudentData(), I have an Ajax request.
I want to Bypass Ajax request in my unit test case using Mocha , so that when i make a call to getStudentData(), the data should be returned.
Please find the code below:
getStudentData: function() {
return studentData || (studentData = new Promise(function(resolve, reject) {
var request = {
//request data goes here
};
var url = "/student";
$.ajax({
url: url,
type: "POST",
data: JSON.stringify(request),
dataType: "json",
contentType: "application/json",
success: function(response, status, transport) {
//success data goes here
},
error: function(status, textStatus, errorThrown) {
reject(status);
}
});
}).then(function(data) {
return data;
})['catch'](function(error) {
throw error;
}));
}
Please let me know how to Bypass Ajax request By stubbing data using sinon.js .so that when i make a call to getStudentData() , data should be returned.
First of all doing:
then(function(data){ return data; })
Is a no-op. So is:
catch(function(err){ throw err; });
Now, your code uses the explicit construction anti-pattern which is also a shame, it can be minimized to:
getStudentData: function() {
var request = {
//request data goes here
};
var url = "/student";
return studentData ||
(studentData = Promise.resolve($.ajax({
url: url,
type: "POST",
data: JSON.stringify(request),
dataType: "json",
contentType: "application/json" })));
}
Now, that we're over that, let's talk about how you'd stub it. I'd do:
myObject.getStudentData = function() {
return Promise.resolve({}); // resolve with whatever data you want to test
};
Which would let you write tests that look like:
it("does something with data", function() { // note - no `done`
// note the `return` for promises:
return myObj.getStudentData().then(function(data){
// data available here, no ajax request made
});
});
Although in practice you'll test other objects that call that method and not the method itself.
I have two function of jQuery. Both the functions are calling jQuery ajax.
both have property async: false.
In both the function I am redirecting on basis of some ajax response condition.
In the success of first function I am calling the another function and then redirecting to another page. But my first function is not redirecting because my second function is not waiting of the response of the first function.
Hope problem is clear from my question.
my first function is as below
function fnGetCustomer() {
function a(a) {
$("#loading").hide();
//on some condition
//other wise no redirection
self.location = a;
}
var b = $("input#ucLeftPanel_txtMobile").val();
"" != b && ($("#loading").show(), $.ajax({
type: "POST",
url: "Services/GetCustomer.ashx",
data: { "CustMobile": b },
success: a,
async: false,
error: function () {
$("#loading").hide();
}
}));
}
and my second function I am calling the first function
function fnSecond() {
$.ajax({
type: "POST",
url: "some url",
async: false,
data: { "CustMobile": b },
success: function(){
fnGetCustomer();
//if it has all ready redirected then do not redirect
// or redirect to some other place
},
error: function () {
$("#loading").hide();
}
}));
}
I am using my first function all ready. So I don't want to change my first function.
A set up like this should work;
$.ajax({
data: foo,
url: bar
}).done(function(response) {
if (response == "redirect") {
// redirect to some page
} else {
$.ajax({
data: foo,
url: bar
}).done(function(response2) {
if (response2 == "redirect") {
// redirect to some other page
} else {
// do something else
}
});
}
});
I've not tested doing something like this, but that's roughly how I'd start off
If you don't need the result of the first AJAX call to be able to send the second you could add a counter to keep track of the calls. Since you can send both calls at the same time it'll be a lot more responsive.
var requestsLeft = 2;
$.ajax({
url: "Firsturl.ashx",
success: successFunction
});
$.ajax({
url: "Secondurl.ashx",
success: successFunction
});
function successFunction()
{
requestsLeft--;
if (requestsLeft == 0)
doRedirectOrWhatever();
}
If you absolutely need to do them in order you could do something like this. My example expects a json response but that's no requirement for this approach to work.
var ajaxurls = ["Firsturl.ashx", "Secondurl.ashx"]
function doAjax()
{
$.ajax({
url: ajaxurls.shift(), // Get next url
dataType: 'json',
success: function(result)
{
if (result.redirectUrl) // or whatever requirement you set
/* redirect code goes here */
else if (ajaxurls.length>0) // If there are urls left, run next request
doAjax();
}
});
}
doAjax();