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

Utilização do Resolve em $routeProvider

Boa tarde!

Estou utilizando a funcionalidade Resolve nas configurações de rotas, onde precisaria executar duas ações respeitando a sequência, mas não estou conseguindo ter êxito.

Abaixo segue o código da minha aplicação.

<!-- Factory -->
angular.module("lancamentoHoras").factory("registroAPI", function($http, config)
{
    var _getRegistros = function () {
        return $http.get(config.baseUrl + "/registro");
    };

    return {
        getRegistros:  _getRegistros
    };

});

<!-- Config -->
angular.module("lancamentoHoras").config(function($routeProvider)
{
    $routeProvider.when("/registro", {
            templateUrl: "view/registroView.html",
            controller:  "registroController",
            resolve: {
                registros: function(registroAPI) {
                    return registroAPI.getRegistros();
                  }
           registrosMap: utilizar os dados retornados do serviço de registro para criar um novo array utilizando a função MAP
           }
    });
});

Basicamente preciso criar uma função que utilize os dados retornados do serviço de getRegistros() e devolva um novo array utilizando a função MAP.

Abraço!

11 respostas

Apesar deu não abordar o uso do resolve no treinamento posso tentar ajuda-lo. O que acontece quando você diz que não teve êxito? Executa fora da ordem ou nada acontece? E o console, qual mensagem é exibida, se é exibido alguma coisa?

Passe essas informações para a gente.

Aproveito para dizer que o curso de Mean foi refeito. Vi que você fez o antigo.

Oi Flávio, tudo bem?

A função registros é executado normalmente, o que precisaria é, em seguida, pegar os dados gerados desta função, tratar eles e atribuir a registrosMap, mas mantendo a ordem de execução. Não sei se consegui ser claro.

Legal, vou dar uma olhada no Mean novamente.

Talvez, para eu tentar te ajudar, se você escrevesse o código do seu registroMAP vai me ajudar a ver o big picture. Porque pelo o que eu entendi, em você quer no resolve, disponbilzar dois dados para um controller, um que são os registros e outros que são os registros transformados. Certo? Dai nesse seu controller vc quer que um seja executada antes do outro.

Cole mais partes do seu código. Mesmo que eu não resolva ou não tenha tempo hábil de te dar uma resposta, fica registado para outras pessoas podem também tentar te ajudar nesse problema específico.

Aguardo seu feedback. Aliás, seu sei porque você está usando o resolve. Não quer que a view associada ao controller fique em branco esperando os dados. Vc quer que ela exiba apenas a view (parcial) quando os dados já estiverem disponíveis. Não é isso? É para isso que o povo usa o resolve, ou está usando para outra finalidade?

Oi Flavio, tudo bem?

Estou utilizando o Resolve justamente para que o controller da minha view não fique com os dados em branco. Estou precisando preencher um campo do tipo SELECT em minha view, justamente com os dados mapeados pela função registroMAP.

Porém, para isto, necessito que primeiro seja executada a função registros e, com estes dados, aplicar a função MAP do JavaScript e gerar um novo array atribuindo para a função registroMAP.

Abaixo segue o código no arquivo de configuração de rotas.

angular.module("lancamentoHoras").config(function($routeProvider)
{
     var dados = [];

    $routeProvider.when("/registro", {
        templateUrl: "view/registroView.html",
        controller:  "registroController",
        resolve: {
            registros: function(registroAPI) {
                dados = registroAPI.getRegistros();
                return dados;
            },
            projetosMAP: function() {
                var projetos = dados.data.map(function(elem) {
                    var projeto = {projetoId : elem.projetoId, projeto : elem.projeto };
                    return projeto;
                });
                return projetos;
            }
        }
    });
});

No meu controller, estou chamando da seguinte maneira.

angular.module("lancamentoHoras").controller("registroController", function($scope, $http, registroAPI, registros, projetosMAP)
{
    $scope.registros  = registros.data;
    $scope.projeto     = projetosMAP.data;
});

Porém, não está retornando nenhum dado. Coloquei alguns console.log(new Date().getTime()) nos pontos de chamadas, e pelo prints realizados, ele executa a função registros e, logo em seguida, executa registrosMAP. Como a chamada ao banco é assíncrona, quando vai executar a função registrosMAP, ainda não possui os dados da função registros, deixando os dados em branco. Por isso, preciso que as funções dentro do resolve sejam executas em sequencia e somente seja executada a registrosMAP após o término da registros.

Abraço!

E esse mesmo o problema por causa do assíncrono. Porque você não cria no service uma função chamada init que busca e realiza o map disponibilizando os dois dados no service. Daí no resolve vc só pega os dados. Faz sentido?

Oi vc tenta transformar no resolve na função que faz o map em uma promise. Na primeira vc retorna uma promises e na segunda não devolve promise . Se não me engano o resolve tem que resolver promises. Ainda assim isso não vaí garantir a ordem. Veja a primeira solução.

Oi Fernando? Resolveu?

solução!

Bom dia Flavio, tudo bem?

Resolvi o problema, adicionando um $watch no meu controller, pois como há inclusão, edição e exclusão de registros, preciso controlar a variável e realizar o MAP em seguida.

Excelente!

Conforme o Flavio passou, o problema é resolvido se você retornar uma promisse.

var deferred = $q.defer();

            serServico.chamaSeuMetodo()
                    .then(function(dados) {
                        deferred.resolve(dados.retorno);
                    })
                    .catch(function(erro) {
                        deferred.reject("Deu algum problema ao fazer a consulta");
                    });

                    return deferred.promise;

Fazendo isso, o controller só será chamado após o deferred.resolve for chamado. Mas lembre-se, se der algum problema e você chamar o deferred.reject, a página não será redirecionada.