I have one button on clicking I need multiple things need to be done, so I went for AJAX and PHP:
$('.go_nxt_lsn').live('click',function(e){
e.stopPropagation();
var user_id = $('input[name=user_id]').val();
var course_id = $('input[name=course_id]').val();
var taskName = "SaveActivity";
var subTask = "watchvideo";
var lesson_id = $(this).attr('data-lesson-id');
var video_id = $(this).attr('data-video-id');
var course_box = '.course_'+course_id;
var refresh_boo = 1;
$.ajax({
type : 'POST',
url : '<?php echo $vars['url']?>learn/pages/syllabus/saveitems.php',
datatype : 'html',
data : {subtask:subTask,lessonid:lesson_id,theSubModID:video_id,userid:user_id,prodid:course_id,taskname:taskName},
success:function(data)
{
taskName = "GoToNextLesson"
$.ajax({
type : 'POST',
url : '<?php echo $vars['url']?>learn/pages/syllabus/saveitems.php',
datatype : 'html',
data : {subtask:subTask,lessonid:lesson_id,userid:user_id,prodid:course_id,taskname:taskName},
success:function(data)
{
$.ajax({
type : 'POST',
url : '<?php echo $vars['url']?>learn/pages/syllabus/learn.php',
datatype : 'json',
data : {user_id:user_id,course_id:course_id},
success:function(data)
{
$.ajax({
type : 'POST',
url : '<?php echo $vars['url']?>mod/event_calendar/views/default/event_calendar/instantlearn.php',
datatype : 'html',
data : {learn_details:data,refresh_boo:refresh_boo,prodid:course_id},
success:function(data)
{
$(course_box).replaceWith(data);
$(".accordion").accordion({
active: false,
collapsible: true,
heightStyle: "content"
});
}
});
}
});
}
});
}
});
});
I am sending four AJAX requests one by one, so I want an alternate for this. This code works fine. But this is so lengthy. Can anybody suggest how I can minimize it?
-
\$\begingroup\$ This is typical 'tower of doom'. I would consider using promises but first of all you should study your applicaton flow. It looks way too complicated and probably can be simplified. \$\endgroup\$Piotr– Piotr2015年02月07日 13:19:47 +00:00Commented Feb 7, 2015 at 13:19
-
\$\begingroup\$ @Piotr yes...its actually before flex application. In that application its total 6 steps & somehow i managed to do by this stuff. On single click...so actually i m not sure what i have done its standard or not....so that i posted here for some suggestion \$\endgroup\$UI Dev– UI Dev2015年02月09日 04:07:53 +00:00Commented Feb 9, 2015 at 4:07
2 Answers 2
The chain of Ajax calls can be set programmatically, instead of being "hardcoded" as in your code. The next snippet shows a possible approach.
However, as Piotr pointed out, you should study your application a bit more to determine whether that is a good solution.
// First generate an array with all the ajax calls than need to be done, in order.
var ajaxCalls = [
// First ajax
function(){
return $.ajax({
type : 'POST',
url : '<?php echo $vars['url']?>learn/pages/syllabus/saveitems.php',
datatype : 'html',
data : {subtask:subTask,lessonid:lesson_id,theSubModID:video_id,userid:user_id,prodid:course_id,taskname:taskName}
});
},
// Second ajax
function(data){
return $.ajax({
type : 'POST',
url : '<?php echo $vars['url']?>learn/pages/syllabus/saveitems.php',
datatype : 'html',
data : {subtask:subTask,lessonid:lesson_id,userid:user_id,prodid:course_id,taskname:taskName}
});
},
...
// Last function doesn't need to return a promise
function(data){
$(course_box).replaceWith(data);
$(".accordion").accordion({
active: false,
collapsible: true,
heightStyle: "content"
});
}
];
// Every time you run an ajax, you want to set it up so that the next
// ajax will be called as a response. Let's do a function for that:
function callAjax(var index){
var thisAjax = ajaxCalls[index];
// Run the ajax
var promise = thisAjax();
// Set up next one if necessary.
var isLastAjax = (index === (ajaxCalls.length - 1));
if(!isLastAjax){
promise.done(function(){
callAjax(index + 1);
});
}
}
// Call the first one
callAjax(0);
-
\$\begingroup\$ What about the declaring the variables ? \$\endgroup\$UI Dev– UI Dev2015年02月09日 04:36:56 +00:00Commented Feb 9, 2015 at 4:36
-
\$\begingroup\$ @RIADev What do you mean? \$\endgroup\$abl– abl2015年02月09日 13:43:59 +00:00Commented Feb 9, 2015 at 13:43
-
\$\begingroup\$ u didn't declared the parameters...so i asked. \$\endgroup\$UI Dev– UI Dev2015年02月10日 13:26:56 +00:00Commented Feb 10, 2015 at 13:26
As piotr says, this can be made a lot cleaner by using promises (and a helper function):
$('.go_nxt_lsn').live('click',function(e){
e.stopPropagation();
var user_id = $('input[name=user_id]').val();
var course_id = $('input[name=course_id]').val();
var taskName = "SaveActivity";
var subTask = "watchvideo";
var lesson_id = $(this).attr('data-lesson-id');
var video_id = $(this).attr('data-video-id');
var course_box = '.course_'+course_id;
var refresh_boo = 1;
var toSave = {
subtask: subTask,
lessonid: lesson_id,
theSubModID: video_id,
userid: user_id,
prodid: course_id,
taskname: taskName
};
callAjax('learn/pages/syllabus/saveitems.php', 'html', toSave)
.then(function () {
var nextSave = $.extend({}, toSave, { taskname: "GoToNextLesson" });
return callAjax('learn/pages/syllabus/saveitems.php', 'html', nextSave);
})
.then(function () {
return callAjax('learn/pages/syllabus/learn.php', 'json', {
user_id: user_id,
course_id: course_id
});
})
.then(function (data) {
var url = 'mod/event_calendar/views/default/event_calendar/instantlearn.php';
return callAjax(url, 'html', {
learn_details:data,
refresh_boo:refresh_boo,
prodid:course_id
});
})
.then(function (data) {
$(course_box).replaceWith(data);
$(".accordion").accordion({
active: false,
collapsible: true,
heightStyle: "content"
});
});
}
function callAjax(page, dataType, data) {
return $.ajax({
type : 'POST',
url : '<?php echo $vars['url']?>learn/pages/syllabus/' + page,
datatype : dataType,
data : data
});
}