Search code examples
javascriptfetchjinja2

How to check if two fetches were conclude and start other action?


I have one onchange event and inside it, I'm calling two fetches. I need to get the response of these fetches and perform one action. But, as the fetch are async, the actions don't perform correctly. There is a way to use something like "wait for these fetches finish and then to this?"

Obs: I'm using Javascript and Jinja2 in the code below

{% for row in tbl_cli %}
<script>
  
        
         document.getElementById("{{ row['ID_ROW_GRTE'] }}").onchange = function(){
            inicial =  document.getElementById("{{ row['ID_ROW_GRTE'] }}").value.lastIndexOf("(");
            final =  document.getElementById("{{ row['ID_ROW_GRTE'] }}").value.lastIndexOf(")");
            codag_para =  document.getElementById("{{ row['ID_ROW_GRTE'] }}").value.substring(inicial+1,final);
            cnpj_tp = document.getElementById("{{ row['ID_ROW_GRTE'] }}_{{ row['CD_CPF_CNPJ'] }}_{{ row['CD_T_PES'] }}").innerHTML;
            chave = codag_para + "_" + cnpj_tp
            codag_de = document.getElementById("codag_{{ row['ID_ROW_GRTE'] }}").innerHTML;
            segmento_de = document.getElementById("segmento_de_{{ row['ID_ROW_GRTE'] }}").innerHTML;
        
            fetch('/select_cli/' + chave).then(function(response){
                response.json().then(function(data){
                    //let optionHTML = '<option value="" disabled selected>Selecione o Gerente</option>';
                    let optionHTML = '';
                    
                    json_string = JSON.stringify(data)
                    count = json_string.length; //se o tamanho da string for maior que 15, então tem conta corrente
                    
                    cta_corrente = json_string.substring(json_string.lastIndexOf(':')+1,json_string.lastIndexOf(']')-1)
                    if (count > 15) {
                        optionHTML += '<i class="fa fa-check-circle" aria-hidden="true" style="color: green"></i>';
                        document.getElementById("cc_dest_flag_{{ row['ID_ROW_GRTE'] }}").value = cta_corrente;
                    } else {
                        optionHTML += '<i class="fa fa-times-circle" aria-hidden="true" style="color: red"></i>';
                    }

                    document.getElementById("cc_dest_{{ row['ID_ROW_GRTE'] }}").innerHTML = optionHTML;

                    });
                });
            
            
            
            fetch('/select_codag/' + codag_para).then(function(response){
            response.json().then(function(data){
                let optionHTML = '';
                

                json_string = JSON.stringify(data)
                segmento_para_ini = json_string.lastIndexOf(":")
                segmento_para_fim = json_string.lastIndexOf('"')
                segmento_para = json_string.substring(segmento_para_ini+2,segmento_para_fim)

                codag_de = codag_de.substring(1,6)


                if (segmento_para == segmento_de && codag_de == codag_para) {
                    optionHTML += 'Mesmo Segmento <br> Mesma Agência';
                } else if (segmento_para == segmento_de && codag_de != codag_para) {
                    optionHTML += ' Mesmo Segmento <br> Nova Agência';
                } else if (segmento_para != segmento_de) {
                    optionHTML += ' Novo Segmento <br> ' + segmento_para;
                } else {
                    optionHTML += ' Movimento não mapeado'
                }
                
                document.getElementById("movimento_{{ row['ID_ROW_GRTE'] }}").innerHTML = optionHTML;

                });
            });
 ############## DO SOMETHING AFTER THE FETCHS #################################

            };  


</script>  
{% endfor %}

Thanks in advance for any help


Solution

  • Since fetch returns promises you could run them sequentially using then or in parallel using Promise.all.

    For example, having:

    const selectCli = () => {
      return fetch(…)
    }
    const selectCodag = () => {
      return fetch(…)
    }
    

    Using then, they would be called one after the other:

    selectCli.then(selectCodag).then(() => console.log("both done"))
    

    Using Promise.all they would be called in parallel:

    Promise.all([
      selectCli,
      selectCodag,
    ]).then(() => console.log("both done"))