0

I'm struggling to implement deferred to get async ajax response. I have this setup:

report.js

function getReport(ref)
{
   $.ajax({
        url: "report.php", 
        dataType: 'json',
        data: { 
            ref: ref,
        },
        success: function(result){
           return (result);
           }
         }
    });
}

index.html

<script>
function firstFunction() {
console.log ("start");
getReport(2, 'queue', 'hour', '2018-09-09', '2018-09-10', 'pageviews', 'page', 's1390_5bbb4639ff37');
};
var test = firstFunction();
alert(test);
</script>

Currently I get "undefined" returned straight away because the alert box doesn't wait for the ajax function to run. Using some tutorials online i've tried to implement it this way:

report.js

function getReport(ref)
{
   var deferred = $.Deferred();
   $.ajax({
        url: "report.php", 
        dataType: 'json',
        data: { 
            ref: ref,
        },
        success: function(result){
           deferred.resolve(result);
           }
         }
    });
  returned deferred.promise();
}

index.html

    <script>
    function firstFunction() {
    console.log ("start");
    getReport(2, 'queue', 'hour', '2018-09-09', '2018-09-10', 'pageviews', 'page', 's1390_5bbb4639ff37');
    };
$.when(getData()).done(function(value) {
    alert(value);
});

getData().then(function(value) {
    alert(value);
});
</script>

I've obviously made a few mistakes on the way because I'm getting the errors below and I can't seem to get past it:

Uncaught SyntaxError: Unexpected identifier
index2.html:12 start
index2.html:13 Uncaught ReferenceError: getReport is not defined
    at firstFunction (index2.html:13)
    at index2.html:16
halfer
  • 19,824
  • 17
  • 99
  • 186
Jimmy
  • 12,087
  • 28
  • 102
  • 192
  • 1
    `getReport` is not returning the Promise created by `$.ajax`... – CertainPerformance Oct 08 '18 at 16:04
  • @CertainPerformance Sorry I don't understand - is it because it doesnt have result in the brackets? – Jimmy Oct 08 '18 at 16:07
  • 2
    You also need to use `return`, not `returned` in Javascript. – CertainPerformance Oct 08 '18 at 16:07
  • 2
    Pretty sure there is an extra `}` in your ajax call, right at the end of the success function, but there is more than one error in this code. Like `return` being `returned`. – Kamil Jarosz Oct 08 '18 at 16:12
  • @KamilJarosz You are right but that's only because I trimmed out one of the simple if commands to make this question more simple but missed that – Jimmy Oct 08 '18 at 16:14
  • @CertainPerformance I see your error about "return" and I have fixed that but I'm really sorry but I don't understand your point on deferred. What do you mean by it has nothing to do with the ajax call, since it is in the success call as well as at the bottom of the function? I know you must be right, but I don't see what you are saying the error is – Jimmy Oct 08 '18 at 16:22
  • Oh, I see the `deferred.resolve` now, sorry. Not sure what the issue is, but personally, I'd ditch the jQuery implementation and use something that uses native Promises like `fetch` instead, `fetch` is far easier to use and doesn't require a big library. – CertainPerformance Oct 08 '18 at 16:24
  • You should not use the [deferred antipattern](https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it). – t.niese Oct 08 '18 at 16:29

1 Answers1

1

I think the addition of the deferred object in getReport is unnecessary because $.ajax already creates one for you. It might be better to modify your original code this way:

function getReport(ref)
{
   return $.ajax({ // Return the deferred object here. It is returned by .ajax()
        url: "report.php", 
        dataType: 'json',
        data: { 
            ref: ref,
        } // Remove the callback here. 
          // You cannot call return in the way you're trying here. 
          // The context is different and outside of normal flow.
    });
}

then in your index file:

<script>
function firstFunction() {
  console.log ("start");
  // You must return the returned value here as well, otherwise variable `test` is going to be undefined.
  return getReport(2, 'queue', 'hour', '2018-09-09', '2018-09-10', 'pageviews', 'page', 's1390_5bbb4639ff37');
};
var test = firstFunction(); // test is now a deferred object
test.done(function(data) {
  alert(data);
});
</script>
Kamil Jarosz
  • 361
  • 1
  • 10