2

I'm having trouble with an array and I cannot find what exactly is the problem.

First a function executes the following two lines in a loop:

varArray[overlapCounter] = [a, b, c];
overlapCounter++;

If I run console.log(varArray), the chrome log gives me the following:

[]

By opening the brackets this is the contents:

Array[0]
0: Array[6]
1: Array[6]
2: Array[6]
3: Array[6]
4: Array[6]
5: Array[6]
6: Array[6]
7: Array[6]
8: Array[6]
9: Array[6]
10: Array[6]
11: Array[6]
12: Array[6]
13: Array[6]
14: Array[6]
15: Array[6]
16: Array[6]
17: Array[6]
18: Array[6]
19: Array[6]
20: Array[6]
21: Array[6]
22: Array[6]
23: Array[6]
24: Array[6]
25: Array[6]
26: Array[6]
27: Array[6]
28: Array[6]
29: Array[6]
30: Array[6]
length: 31
__proto__: Array[0]

But if I run console.log(varArray.length), the value is 0, and console.log(varArray[0]) returns undefined.

Does anyone know what is going on there?

Full code:

$('#Salvar').click(function(e) {
          e.preventDefault();
          var dt_inicio_afastamento = $('#dt_inicio_afastamento').val();
          var dt_fim_afastamento = $('#dt_fim_afastamento').val();
          var observ_afastamento = $('#observ_afastamento').val();
          var id_ocorrencia = $('#id_ocorrencia').val();
          if ( dt_inicio_afastamento === "" || dt_fim_afastamento === "" || id_ocorrencia === ""){
            return swal({
                    title: 'Todos os campos são obrigatórios!', 
                    type: 'warning'
                });
          }
          else{
            function ajax2(names, dt_inicio_afastamento, dt_fim_afastamento, id_docente, observ_afastamento, id_ocorrencia){  
              $.ajax({
                url: '../engine/controllers/afastamento.php',
                data: {
                  id_afastamento  : null,
                  dt_inicio_afastamento : dt_inicio_afastamento,
                  dt_fim_afastamento : dt_fim_afastamento,
                  observ_afastamento : observ_afastamento,
                  id_ocorrencia : id_ocorrencia,
                  id_docente : id_docente,
                  action: 'create'
                },
                error: function() {
                  swal({ 
                      title: 'Erro na conexão com o servidor',
                      text :'Tente novamente em alguns segundos',
                      type: 'error'
                  });
                },
                success: function(data) {
                  //console.log(data);
                  if(data === 'true'){
                    names.css( "background-color", "lightgreen" );
                  }
                  else{
                   names.css( "background-color", "lightcoral" );
                  }
                }, //Sucesso Ajax2
                type: 'POST'
              }); //Ajax2
            }
            var overlapCounter = 0;
            var varArray = [];
            var requests = [];
            $(".cada_docente").each(function(index) {
              var names = $(this).prev();
              var id_docente = $(this).val();
              var nomeSerie = names.children('.nomeSerie').text();
              var requests = Array();
              (function(names, nomeSerie, dt_inicio_afastamento, dt_fim_afastamento, id_docente, observ_afastamento, id_ocorrencia){
                requests.push($.ajax({
                  url: '../engine/controllers/afastamento.php',
                  type: 'POST',
                  data: {
                    id_afastamento  : null,
                    dt_inicio_afastamento : dt_inicio_afastamento,
                    dt_fim_afastamento : dt_fim_afastamento,
                    observ_afastamento : observ_afastamento,
                    id_ocorrencia : id_ocorrencia,
                    id_docente : id_docente,
                    action: 'overlap'
                  },
                  success: function(data) {
                    if (data == "true"){ajax2(names, dt_inicio_afastamento, dt_fim_afastamento, id_docente, observ_afastamento, id_ocorrencia);}
                    else{
                        varArray[overlapCounter] = [names, dt_inicio_afastamento, dt_fim_afastamento, id_docente, observ_afastamento, id_ocorrencia];
                        overlapCounter++;
                    } 
                  } //Sucesso Ajax1
                })); //Ajax1
              })(names, nomeSerie, dt_inicio_afastamento, dt_fim_afastamento, id_docente, observ_afastamento, id_ocorrencia); //Ajax1 Função
            }); // Cada Docente
            var defer = $.when.apply($, requests);
            defer.done(function(){
                console.log(varArray);
                });


          } //Else dados colocados
        });
gyre
  • 16,369
  • 3
  • 37
  • 47
Ricardo Melo
  • 459
  • 1
  • 4
  • 14
  • Please show the code in context. Is it asynchronous? When you log an object (including arrays), the console keeps a live reference to the object, so even if it was empty at the moment it was logged, by the time you click on it it may have been populated. The `.length`, however, is logged as it was at the time. – nnnnnn Mar 24 '17 at 05:13
  • Could you please post the full code here? – codemirror Mar 24 '17 at 05:14
  • the full code of the function is a monster right now, but alright, i'll post it: – Ricardo Melo Mar 24 '17 at 05:14
  • can you do `console.log(varArray, varArray.length);` and tell what it logs? – Yogesh Mistry Mar 24 '17 at 05:15
  • console.log(varArray, varArray.length); returns [] 0. when opened, there are many arrays inside the []. – Ricardo Melo Mar 24 '17 at 05:17

1 Answers1

16

Your problem is that console.log is not guaranteed to be synchronous; for object references like arrays, when you view the object's property tree you are seeing the tree as it is currently rather than as it was when you called log. Integers, on the other hand, are passed by value and thus when you log(array.length) you get the value of the length at the very instant log was called.

If you want to print the array as it as when you called log, you should first make a copy of it using array.slice() (note that this only creates a shallow copy of the array):

console.log(array.slice())
gyre
  • 16,369
  • 3
  • 37
  • 47
  • The fact that it is inside a defer.done(function(){ console.log(varArray); }); doesnt change this behaviour? – Ricardo Melo Mar 24 '17 at 05:20
  • 1
    No, it does not. You will have to use `array.slice()` as I suggested above if you want to take a snapshot of the object structure at that instant. – gyre Mar 24 '17 at 05:21
  • console.log(varArray.slice()); logs even less than before :/ Now its just an empty array with length 0, before it was logging all the arrays inside as well. – Ricardo Melo Mar 24 '17 at 05:22
  • So what are you trying to log? The updated value of the `length` property? You will have to view that inside the array reference when you print it. – gyre Mar 24 '17 at 05:23
  • the log is just the start, I want to actually use the values inside of varArray, but I can't get the length, or the individual arrays inside varArray, apart form logging the entire thing, javascript returns anything I try to do as undefined... – Ricardo Melo Mar 24 '17 at 05:24
  • That means your array hasn't been filled by the time your `log` statement is called. You mentioned you were doing this inside of a `Deferred`; I would suggest posting that entire code as a new question and trying to find out why it is not working as intended. – gyre Mar 24 '17 at 05:25
  • Alright, I did post the entire code in this question but its quite huge... – Ricardo Melo Mar 24 '17 at 05:26
  • Please post this as a **new question**, since this question has been marked as a duplicate already. – gyre Mar 24 '17 at 05:27