0

I am sending data to a PHP script using an Ajax call, and I intend to use the Ajax return value in a Javascript function.

I have tried using return $.ajax({}) and it doesn't work. I also tried registering a callback function in my Ajax call, and that didn't work as well. Is there something am not doing right here?

function click_to_showResult() {
    var score;
    if (userName !="") {
        var result = getResultData();
        //display result for selected user
        if (result == "Distinction") {
            score ="A";
        } else if (result =="Pass") {
            score ="C";
        } else {
            score ="User has no result in DB";
        }
    }

    alert(score);

}

function getResultData(callback) {
    var data;
    var userName = $.trim($("#user").val().toLowerCase()); //gets username input from the user
    $.ajax({
        type:"POST",
        url : "getResult.php",
        data: {'name':user},
        success: function(resp) {
            data = resp;
        },
        error: function(resp) {
            alert('Error occured');
        }
    });
    return data;
}               

Let's say the user inputs Mike, then it should send the variable to PHP and get the results for Mike (for instance Pass), then alert C.

Laurenz Albe
  • 209,280
  • 17
  • 206
  • 263
Jay
  • 53
  • 9
  • `ajax` is, as the name suggests, `asynchronous` in nature by default so the function can return before the response. In order to use the response either use `fetch` or wrap the ajax call in a `Promise` – Professor Abronsius Jul 10 '19 at 14:19
  • @RamRaider can u giv me a clue on how to achieve such using Promise. am still learning Ajax. – Jay Jul 10 '19 at 15:43
  • @RamRaider... why declare constant as in this const click_to_showResult=function(e). is it necessary? – Jay Jul 10 '19 at 15:44
  • nope, not really. it is another way of defining a function but can easily use the older style notation `function click_to_showResult(){}` – Professor Abronsius Jul 10 '19 at 15:47
  • 1
    You should always properly space and indent your code. Otherwise you won't be able to read it any more, and it will be doubly hard to find bugs. I tried to do it for you by editing your question. – Laurenz Albe Jul 10 '19 at 17:24
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – ADyson Jul 10 '19 at 17:39

2 Answers2

1

You should use the callback like this.

function click_to_showResult() {
  var userName = $.trim($("#user").val().toLowerCase()); //gets username input from the user
  if (userName != "") {
    getResultData(userName, function (err, result) {
      if (err) { console.log(err); return; }
      var score;
      //display result for selected user
      switch (result) {
        case "Distinction":
          score = "A";
          break;
        case "Pass":
          score = "C";
          break;
        default:
          score = "User has no result in DB";
      }
      alert(score);
    });
  }
}

function getResultData(userName, callback) {
  $.ajax({
    type: "POST",
    url: "getResult.php",
    data: { 'name': userName },
    success: function (resp) {
      callback(null, resp);
    },
    error: function (resp) {
      callback('Error occured');
    }
  });
} 
  • please explain this line: callback(null, resp);. why the null parameter? – Jay Jul 11 '19 at 05:14
  • 1
    @Jay the first parameter of that callback is reserved for an `error`. If you look at the error callback, the callback is called with the first param as `'Error occured'`. So at the success callback, the `null` parameter means that there's no error. – phuwin Jul 11 '19 at 08:47
  • @phuwin..tnx u for the explanation. its clearly understood now – Jay Jul 11 '19 at 09:09
0

If I understood correctly then you could perhaps rewrite the above code like this - the callback will process the response and alert the user. One issue I spotted after making the above comment was the data you send was user but this does not appear to be defined within the function - I suspect you intended userName?!

const click_to_showResult=function(e){

    let userName=$.trim( $('#user').val().toLowerCase() );
    if( userName!='' ){

        /* callback function to process the response data */
        const gradecallback=function( r ){
            let score;
            switch( r ){
                case 'Distinction':score='A';break;
                case 'Pass':score='C';break;
                default:score='User has no result in DB';break;
            }
            alert( score );
        };

        $.ajax({
            type: 'POST',
            url : 'getResult.php',
            data: { 'name':userName },  /* previously supplying user rather than userName */
            success: function( resp ){
                gradecallback.call( this, resp );
            },
            error: function(resp){
                alert('Error occured');
            }
        }); 
    }
}

<?php
    if( $_SERVER['REQUEST_METHOD']=='POST' ){
        ob_clean();
        /* 
            do db lookup or whatever tasks the getResults.php 
            script actually does and send the response.

            For the purposes of the demo send back some data
            which might or might not reflect the actual data
            from getResult.php... 

            Open the console to view output
        */
        $name=$_POST['name'];
        $score=mt_rand(0,100);

        if( $score >= 75 )$grade='Distinction';
        elseif( $score > 50 && $score < 75 )$grade='Merit';
        elseif( $score > 40 && $score < 50 )$grade='Pass';
        else $grade='Fail';


        $payload = json_encode( array( 'name'=>$name, 'score'=>$score, 'grade'=>$grade ) );


        /*
            sleep is used ONLY to indicate that this backend process MIGHT take some time to perform ALL
            the actions that are done by getResult.php
        */
        sleep( 2 );
        exit( $payload );
    }
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8' />
        <script src='//code.jquery.com/jquery-latest.js'></script>
        <script>
            document.addEventListener('DOMContentLoaded',e=>{

                let SCORE=false;


                /* AJAX function bound with a promise to send POST requests only */
                const ajax=function(url,params){
                    return new Promise( function( resolve, reject ){
                        let xhr=new XMLHttpRequest();
                        xhr.onload=function(){
                            if( this.status==200 && this.readyState==4 ){
                                /* 
                                The request has completed and the response is available. 
                                Resolve the Promise with the response data
                                */
                                resolve( this.response )
                            }
                        };
                        xhr.onerror=function( error ){
                            reject( error )
                        };
                        xhr.open( 'POST', url, true );
                        xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                        xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
                        xhr.send( params );
                    });
                };

                const alt__click_to_showResult=function(){
                    /*
                        asynchronous functions do not necessarily complete in the order
                        you would imagine like a standard synchronous function does
                        which is why returning a value from them is harder
                    */
                    console.info('called before asynchronous request bound in a Promise');

                    let url=location.href;
                    let params='name='+document.getElementById('user').value;

                    ajax( url, params ).then(
                        res=>{
                            /* The Promise has been resolved */
                            console.info('The asynchronous request has now completed - trigger ajax callback');
                            return ajax_callback( res );
                        }
                    ).then(
                        /* this is the value returned by the ajax_callback */
                        res=>{ 
                            console.info( 'The ajax callback returned this data: %o',res );
                            return true;
                        }
                    ).then(
                        res=>{
                            alert( 'all done....'+res )
                        }
                    ).catch(
                        /* For some reason the promise was rejected*/
                        e=>{ alert(e) }
                    )
                    console.info( 'After asynchronous request' );
                };

                /* do something with the data */
                const ajax_callback=function(res){
                    SCORE=JSON.parse( res );
                    console.info( 'The user "%s" scored %s which is a grade "%s"', SCORE.name, SCORE.score, SCORE.grade )
                    /* modify the data to indicate that it has been intercepted and processed - only to show flow of data*/
                    SCORE.banana='yellow';
                    return SCORE
                };





                /* a slightly modified version of previously posted function */
                const click_to_showResult=function(e){

                    let userName=$.trim( $('#user').val().toLowerCase() );
                    if( userName!='' ){

                        /* callback function to process the response data */
                        const gradecallback=function( r ){
                            let json=JSON.parse( r );// process JSON response rather than plain text as before
                            let score;

                            switch( json.grade ){
                                case 'Distinction':score='A';break;
                                case 'Merit':score='B';break;// added this...
                                case 'Pass':score='C';break;
                                default: score='User has no result in DB';break;
                            }
                            alert( 'User: '+json.name+' Scored: '+json.score+' Award: '+json.grade+' Grade:'+score );
                        };

                        $.ajax({
                            type: 'POST',
                            url : location.href, // "getResult.php"
                            data: { name:userName },  /* previously supplying user rather than userName */
                            success: function( resp ){
                                gradecallback.call( this, resp );
                            },
                            error: function(resp){
                                alert('Error occured');
                            }
                        }); 
                    }
                }

                document.querySelector( 'form > input[type="button"][name="std"]' ).addEventListener( 'click', click_to_showResult )
                document.querySelector( 'form > input[type="button"][name="alt"]' ).addEventListener( 'click', alt__click_to_showResult )
            });
        </script>
    </head>
    <body>
        <form method='post'>
            <input type='text' name='user' id='user' value='geronimo' />
            <input type='button' name='std' value='Click to show results' />
            <input type='button' name='alt' value='Alternative - Click to show results' />
        </form>
    </body>
</html>
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46
  • it stil didnt call . At first, its difficult writing a gradecallback function in a block(within a function). i have to write the function in an outer block, then replace this line : const gradecallback=function(r){. with gradecallback(r). Then function gradecallback(){ //statements}. nothing is output. the browser stays still. – Jay Jul 10 '19 at 17:21
  • Not sure why you say "it still didn't call" but have put together a demo with the above(modified slightly) and a Promise bound example. – Professor Abronsius Jul 11 '19 at 08:23
  • i don't mean to sound rude, am just a beginner and the above modified codes looks complex to me . Anyways i have gotten a solution. tnx alot for your efforts in solving my problem – Jay Jul 11 '19 at 11:06