Solucionado (ver solução)
Solucionado
(ver solução)
6
respostas

Sincronizar consulta

Bom dia, tudo bem?

Gostaria de tirar uma duvida, é com relação ao sincronismo, escrevi um código abaixo de um exemplo que estou tendo dificuldade de como implementar da melhor forma, se alguém puder me ajudar agradeço.

Seria a sincronização da consulta no banco de dados com a sequencia das outras funções na sequencia do código.

Quando chamada a função inicializar é colocado dentro da variável qtdDadosBD o resultado da quantidade de linhas da consulta qtdDadosBD(), porém, como sabemos as funções são executadas de forma assíncrona, ou seja, na linha do IF abaixo, a variável qtdDadosBD ainda esta undefined, falhando a ideia do código.

Gostaria, se possível, se alguém pudesse escrever esse mesmo código de exemplo, de tal forma que a parte do if() só seja executada após terminar a consulta ao BD executada acima, mantendo a consulta em uma função separada.

Desde já agradeço a atenção.

    $scope.inicializar = function(){

        $scope.dadosFixos = [{descricao: 'teste'}, {descricao: 'teste'}, {descricao: 'teste'}]

        var qtdDadosBD = $scope.qtdDadosBD();      

    //Como executar esse IF, somente depois da consulta acima qtdDadosBD() terminar
        if($scope.dadosFixos.length != qtdDadosBD){
            $scope.atualizaDadosBD($scope.dadosFixos.length, qtdDadosBD);
        }
    }

    $scope.qtdDadosBD = function() {

        DatabaseValues.setup();
        DatabaseValues.bancoDeDados.transaction(function(transacao){
            transacao.executeSql('SELECT * FROM dados', [], function(transacao, resultados){

                return resultados.rows.length;
            })
        })
    }
6 respostas

Olá Marcelo.

Basta chamar o código que vc quer (no seu caso, esse IF) na função de callback executeSql

Boa tarde Lazaro, da uma olhada se eu entendi o que você quis dizer no código abaixo, colocar o IF no callback do executeSQL.

Se for isso não resolve meu problema, porque eu gostaria de utilizar essa mesma função "$scope.qtdDadosBD();" em vários locais do sistema com outros códigos na sequencia utilizando o valor retornado pela função.

$scope.inicializar = function(){

        $scope.dadosFixos = [{descricao: 'teste'}, {descricao: 'teste'}, {descricao: 'teste'}]

        $scope.qtdDadosBD();      
    }

    $scope.qtdDadosBD = function() {

        DatabaseValues.setup();
        DatabaseValues.bancoDeDados.transaction(function(transacao){
            transacao.executeSql('SELECT * FROM dados', [], function(transacao, resultados){

                if($scope.dadosFixos.length != resultados.rows.length){
                    $scope.atualizaDadosBD($scope.dadosFixos.length, resultados.rows.length);
                }

            })
        })
    }

Não tem como eu transformar essa função $scope.qtdDadosBD() em uma promisse como no nodejs e chamar a sequencia quando terminar de executar a anterior? Se tiver me da uma luz de como fazer esse exemplo. Obrigado!

$scope.qtdDadosBD()
.then()

Oi Marcelo.

Vc pode usar promise sim. Aqui é JS e vc pode usar todo o poder dele.

solução!

Deu certo usando promise Lazaro, obrigado.

Uma nova duvida, tudo roda perfeitamente no browser com WebSQL, quando coloco o aplicativo no celular não da erro mas também não funciona, WebSQL é totalmente compatível no IOS? Estou usando um iPhone 6.

Obrigado!

Oi Marcelo.

A compatibilidade é com o IOS e não com o dispositivo. Eu vi que o WebSQL tem compatibilidade com a versão mais nova do IOS sim.

Tivemos problema aqui com um aluno que tentou usa-lo pelo ionic view e realmente não funcionou. Vc está usando o deploy direto no celular?

Configurações: iPhone 6 com iOS 10.2.1

Isso, abro pelo XCode e rodo direto no celular.

Seu exemplo, dava um erro que não tenho aqui agora porque não estou com o mac no momento, passo quando chegar em casa:

.value('DatabaseValues', {    
    bancoDeDados: null,
    setup: function() {        
        if(!window.openDatabase) {
            alert('não suportado');
        }
        try{                           
            this.bancoDeDados = window.openDatabase('banco', '4.0', 'Descricao', 2000);
        } catch(erro) {
            alert(erro);
        }
    }
})

Alterei pra dessa forma e parou:

.value('DatabaseValues', {    
    bancoDeDados: null,
    setup: function() {        
        if(!window.openDatabase) {
            alert('não suportado');
        }
        try{                   //window.                                
            this.bancoDeDados = openDatabase('banco', '4.0', 'Descricao', 2000);
        } catch(erro) {
            alert(erro);
        }
    }
})

A unica mudança foi tirar o window. da frente do openDatabase, parou de dar o erro, porém, as consultas continuam sem retorno, se tiver alguma dica agradeço.

estimatedSize (number): The expected maximum size of the database, in bytes. As the database increases in size, the user may be prompted for permission. If you make a reasonable first guess, the user is likely to be prompted less often. https://cordova.apache.org/docs/en/latest/cordova/storage/storage.html#websql

Consultei a documentação e o tamanho na criação do BD é definido em bytes, em algumas consultas que fiz na internet tentando achar a solução, reparei que o pessoal definia da seguinte forma:

this.bancoDeDados = openDatabase('banco', '4.0', 'Descricao', 2 * 1024 * 1024);

Vou experimentar aumentar o tamanho nos meus testes também, colocando 2000 como estava no exemplo, creio que estava reservando pouco espaço.

Qualquer sugestão ou dica é bem-vinda professor, desde já agradeço a atenção!