1

I have a function which process some array in sub-process.

The goal is to send the actual array into function and return the array updated (2 values removed).

I am calling the function by:

var resultMaster = [];
resultMaster = traceSystem(traceURL,searchURL,term,master_id,groupID,final_pair,masters);
    console.log('resultMaster:    ' + resultMaster);
    console.log('resultSystem under Master:    ' + masters);

the called function does:

function traceSystem(traceURL,searchURL,term,master_id,groupID,pairKey,masters) {
  var   resultSystem = [];
  ...
  $.ajax({
    url: searchURL,
    type:'post',
    data: jsonQuery,
    dataType: 'text',
    crossDomain: true,
    async: false,
    success: function(response) { 
      ...
        for ( m = 0; m <  system.masters_ids.buckets.length; m++ ) {
          console.log('Removing masterID: ' + system.masters_ids.buckets[m].key); 
          masters = masters.filter(function(e) { return e != system.masters_ids.buckets[m].key }); 
          console.log('resultSystem:    ' + masters);
        };

    }   // Success
  }); //Ajax

  console.log('final result from System:    ' + masters);
  return masters;
};

I supposed that the return masters; will return the array to parent function into the variable resultMaster. But it doesn't.

See log from console:

Array [ "ci1481537045764.949410@czcholsint37…", "ci1481537045768.924200@czcholsint37…", "3b3_87465652", "00000553239291", "ci1481536983712.948609@czcholsint37…", "ci1481536983718.923358@czcholsint37…" ]

Logs from the loop:

Removing masterID: 3b3_87465652
resultSystem:    ci1481537045764.949410@czcholsint373_te,ci1481537045768.924200@czcholsint372_te,00000553239291,ci1481536983712.948609@czcholsint373_te,ci1481536983718.923358@czcholsint372_te

Removing masterID: ci1481537045764.949410@czcholsint373_te
resultSystem:    ci1481537045768.924200@czcholsint372_te,00000553239291,ci1481536983712.948609@czcholsint373_te,ci1481536983718.923358@czcholsint372_te

Log right after the loop:

final result from System:    ci1481537045768.924200@czcholsint372_te,00000553239291,ci1481536983712.948609@czcholsint373_te,ci1481536983718.923358@czcholsint372_teindex-by-masterid.jsp:343:5

Log from parent function after returned value from traceSystem:

resultMaster:    
resultSystem under Master:    ci1481537045764.949410@czcholsint373_te,ci1481537045768.924200@czcholsint372_te,3b3_87465652,00000553239291,ci1481536983712.948609@czcholsint373_te,ci1481536983718.923358@czcholsint372_te

Variable resultMasters seems to be empty.

How to properly return the array from called function?

Added based on @Quentin request:

I have tried to create separate simple example to simulate the behavior and strange is that there is working:

<script type="text/javascript">
            function traceMasterId(masters) {
                var resultMaster = [],
                masters = [];

                masters.push('ci1481537045764.949410@czcholsint373_te');
                masters.push('ci1481537045768.924200@czcholsint372_te');
                masters.push('ci1481536983712.948609@czcholsint373_te');
                masters.push('ci1481536983718.923358@czcholsint372_te');
                masters.push('3b3_87465652');
                masters.push('00000553239291');

                console.log('Masters:    ' + masters);

                resultMaster = traceSystem(masters);

                console.log('resultMaster:    ' + resultMaster);
            };

            function traceSystem(masters) {
                var master_ids = [];

                master_ids.push('ci1481536983718.923358@czcholsint372_te');
                master_ids.push('3b3_87465652');

                for ( m = 0; m <  master_ids.length; m++ ) {
                    console.log('Removing masterID: ' + master_ids[m]); 
                    masters = masters.filter(function(e) { return e != master_ids[m] }); 
                    console.log('resultSystem:    ' + masters);
                };

                console.log('Final result from System:    ' + masters);
                return masters;             

            };

</script>                   

<body onload="traceMasterId();"></body>

See log:

Masters:    ci1481537045764.949410@czcholsint373_te,ci1481537045768.924200@czcholsint372_te,ci1481536983712.948609@czcholsint373_te,ci1481536983718.923358@czcholsint372_te,3b3_87465652,00000553239291test.jsp:14:5
Removing masterID: ci1481536983718.923358@czcholsint372_tetest.jsp:29:6
resultSystem:    ci1481537045764.949410@czcholsint373_te,ci1481537045768.924200@czcholsint372_te,ci1481536983712.948609@czcholsint373_te,3b3_87465652,00000553239291test.jsp:31:6
Removing masterID: 3b3_87465652test.jsp:29:6
resultSystem:    ci1481537045764.949410@czcholsint373_te,ci1481537045768.924200@czcholsint372_te,ci1481536983712.948609@czcholsint373_te,00000553239291test.jsp:31:6
Final result from System:    ci1481537045764.949410@czcholsint373_te,ci1481537045768.924200@czcholsint372_te,ci1481536983712.948609@czcholsint373_te,00000553239291test.jsp:34:5
resultMaster:    ci1481537045764.949410@czcholsint373_te,ci1481537045768.924200@czcholsint372_te,ci1481536983712.948609@czcholsint373_te,00000553239291test.jsp:18:5

I do not see a difference what has been done by other way. Except that the subfunction has been now called only with one parameter.

Reddy SK
  • 1,334
  • 4
  • 19
  • 27
  • 1
    The code says `async: false,` — it isn't an asynchronous call. – Quentin Dec 19 '16 at 08:50
  • This doesn't make sense. You log a value. Return that value. Log the return result. And they are different. I can't think of any situation that would happen under. Can you make your [mcve] more *minimal* and *complete*? – Quentin Dec 19 '16 at 08:52
  • 1
    Worth noting that `async: false` is [deprecated in the spec](https://xhr.spec.whatwg.org/#sync-warning), and you should consider that browsers _could_ start throwing errors at any point, breaking your code. – James Thorpe Dec 19 '16 at 08:53
  • @Quentin I will try ... give me a time – Reddy SK Dec 19 '16 at 08:54
  • so it means james thorpe was correct ? – Mahi Dec 19 '16 at 09:24
  • @Mahi I don't think so. True is that now I have excluded AJAX, but as you can see in first attempt I have reported and returned the **masters** value also directly from the called function. Not from the AJAX .success part. – Reddy SK Dec 19 '16 at 09:26
  • @Quentin, it seems to be problem between chair and keyboard. I have just reformatted rows in the code and it started to work. Probably a hidden character escaped the real return value. – Reddy SK Dec 19 '16 at 09:42

2 Answers2

0

The reported issue seems to be not issue.

I have just reformatted rows in the code and it started to work.

Probably a hidden character escaped the real return value.

Reddy SK
  • 1,334
  • 4
  • 19
  • 27
  • I don't think so: It should be a side effect of some delay (just like executing an `alert("Foo bar");`after calling your function giving the time to the ajax processing to be finished. It would fail in other browsers or in random other situations... – bitifet Dec 19 '16 at 09:49
0

You can't because $.ajax() is (and should be) an asynchronous function.

What is happening is that traceSystem() function returns before your success callback is actually called.

So you are returning masters object before it is actually modified.

Server side you could have been used deasync (nodejs module) but in a browser I think your best bet is to rewrite your code to do it asynchronously.

That is, for example:

  1. Add a callback argument to traceSystem() function.

  2. Call it (passing masters as argument) at the end of the success callback of the $.ajax().

  3. Instead of...

this:

[...]
resultMaster = traceSystem(arg1, arg2...);
console.log('resultMaster: ' + resultMaster);
[...]

...try:

[...]
traceSystem(arg1, arg2... , function(resultMaster){
    console.log('resultMaster: ' + resultMaster);
    [...]
});
bitifet
  • 3,514
  • 15
  • 37