Working with Factory

Asked

Viewed 1,107 times

0

I am developing a system for a snack bar, where she will have to register the cities and within the cities the neighborhoods with their due freight, the problem is occurring the first time that occurs the registration of the first neighborhood of the city, because it follows all logic and tries to reload the function carregarBairros() that is inside another controller, as shown below:

html code

<div ng-hide="consultaativa" class="catalogo md-whiteframe-1dp col-md col-xs-12 col-sm-12 padding-zero" >

    <div  class="texto_catalogo" id="catalogo_{{cidade.cid_atd_id}}" style="padding-top: 30px;">
        <form name="bairroForm" >
            <div style="height:70px;" ng-model="box_alterar" ng-hide="hideAlterar" class="box_alt_bairros">
                <div layout-gt-sm="row" style="width:650px;">
                    <md-input-container flex ng-class="{'md-input-invalid': validaBairro.nomeinv}" >
                        <label>Bairro</label>
                        <input class="moeda" style="width: 300px;" ng-blur="validarBairro(1, validaBairro.nome)" ng-click="validarBairro(0, validaBairro.nome)" ng-keyup="validarBairro(0, validaBairro.nome)" type="text"  name="bairro" ng-model="validaBairro.nome" autofocus />
                        <div  class="error" ng-if="validaBairro.nomeinv" role="alert" multiple>
                            <div ng-message="required" class="my-message">Preencha o campo Bairro</div>
                        </div>
                    </md-input-container>
                    <md-input-container flex ng-class="{'md-input-invalid': validaFrete.freteinv}">
                        <label>Frete</label>
                        <input ng-model="validaFrete.frete" name="frete" ng-blur="validarFrete(1)" ng-click="validarFrete(0)" ng-keyup="validarFrete(0)" id="valor" mask-money style="width: 300px;padding: 0px;" type="text"/>
                        <div class="error" ng-if="validaFrete.freteinv" role="alert" multiple>
                            <div ng-message="required" class="my-message">Preencha o campo Frete</div>
                        </div>
                    </md-input-container>
                </div>
            </div>
            <div class="col-md-3 teste padding-zero pull-right" style="margin-top: 10px;">
                <section layout="row" layout-sm="column" class="pull-right" layout-wrap>
                    <md-button ng-click="cancelarAlteracao()" ng-if="alterar" class="md-raised md-warn pull-right">
                        <i class="fa fa-close"></i>
                        Cancelar
                    </md-button>

                    <md-button ng-click="validaForm(validaBairro.nome, cidade.cid_atd_id)" type="submit" ng-submit="validaForm(validaBairro.nome, cidade.cid_atd_id)" class="md-raised md-primary pull-right">
                        <i class="fa fa-save"></i>
                        Salvar
                    </md-button>
                    <div class="label"></div>
                </section>
            </div>
        </form>


        <div style="height: 50px;"></div>
    </div>
</div>



$scope.validaForm = function (bairro, cidade) {
    var valor = $("#valor").val();
    if ($scope.validaBairro.nomeinv === false && $scope.validaFrete.freteinv === false && $scope.validaBairro.nome !== '' && valor !== '0,00' && valor !== '') {
        if ($scope.alterar === false) {
            $scope.adicionarBairro(bairro, cidade, valor);
        } else {
            $scope.updateBairro($scope.id_bairro, cidade, bairro, valor);
        }
        $scope.validaBairro.nomeinv = false;
        $scope.validaFrete.freteinv = false;
    } else {
        $scope.validarBairro(1, bairro);
        $scope.validarFrete(1);
    }
};

$scope.adicionarBairro = function (bairro, cidade, valor) {
    $http.post(url_sistema + 'mostrarcidades/cadastrar_bairro', {'nome': bairro, 'cidade': cidade}).success(function (data, status, headers, config) {
        delete $scope.bairro; // se nao colocar esta linha, quando alterar o campo ele altera o dado da tabela tambem
        if (data < 1) {
            $http.post(url_sistema + 'mostrarcidades/cadastrar_frete', {'nome': bairro, 'cidade': cidade, 'valor': valor}).success(function (data, status, headers, config) {
                delete $scope.bairro;
            }).error(function (data, status) {
                console.log(data);
            });
            $mdToast.show(
                    $mdToast.simple()
                    .content('Cadastrado com sucesso!')
                    .theme("success-toast")
                    .position("top right")
                    .hideDelay(2000)
                    );
            Scopes.get('mostrarCidadesCtrl').carregarBairros(valor, cidade);
            carregarFretes(cidade);
            $scope.cancelarAlteracao();
            $timeout(function () {
                $scope.selectedIndex = 0;

            }, 10000);
        } else {
            $mdDialog.show(
                    $mdDialog.alert()
                    .clickOutsideToClose(true)
                    .title('O bairro informado já está cadastrado!')
                    .ariaLabel('Existe!')
                    .ok('ok')
                    .targetEvent(event)).then(function () {
            });
        }
    }).error(function (data, status) {
        console.log(data);
    });
};

});


$scope.carregarBairros = function (id_frete, id_cidade) {
    $http.post(url_sistema + 'mostrarcidades/listar_bairros', {'id_frete': id_frete, 'id_cidade': id_cidade}).success(function (data, status, headers, config) {
        $scope.bairros = data;
        console.log(id_cidade);
        if ($scope.bairros.length === 0) {
            $scope.ativo = true;
        } else {
            $scope.ativo = false;
        }
        $timeout(function () {
            Scopes.get('fretesCtrl').bairro(id_cidade);
        }, 3000);
    }).error(function (data, status) { // called asynchronously if an error occurs
        console.log(data);
    });
};

});


print after clicking save

print depois de clicar em salvar


print after pressing F5

print depois de ter pressionado o F5

  • You don’t need to insert all your source code here. Post only the code referring to the problem, the functions that involve the problem you are facing. It is easier to identify than having to read all your code just to look for the functions related to it.

  • Sorry Celsom, it was not my intention, first time I use a forum to help me, can help me with this problem?

  • Yes, no problem, but do a summary of your Anglican codes, because there is a lot there. Just leave the functions related to the problem

  • Okay, I’ve adjusted it so that you’re better off understanding, as requested

  • But it’s still hard to understand.. What is the function to save the new neighborhood? Where is it?

  • it calls the function validaForm, from this function it validates whether it is fit to add the new neighborhood or not and calls the function add if it is fit.

  • Ok, but friend, edit your question and leave ONLY the codes relevant to your question and problem. Ex.: we don’t need your code .run, or definitions of $Scope that have no connection with the function to add neighborhood, or your Factory, for example. Clear your question by leaving only the functions related to the problem. It will be easier to help you.

  • Melhor Celsom?

  • Yes, I’ll analyze it and I’ll answer =D

  • Grateful, I await your answer :P

Show 5 more comments

1 answer

0


Well, first of all, from what I understand, your problem is in performing the second function, since it’s in another controller. Although this is possible, I will recommend that you abandon this method!

The function of the controller is only to promote communication between the DOM and the Services (service, Factory, Directive, etc. ). The controller, following the good practice guide, should not be used to upload data, send data.. This is the work of services.

The easiest solution - but not the best

Move the function $scope.carregarBairros for the same controller of other functions.

//--- End ---\

The most correct solution:

Move the request tasks to a service (serice or Factory - Factory is more common to use), we will use factory.

Within it, you define the functions to be performed:

meuModulo.factory('factoryBairro', function($http) { //Não se esqueça de fazer a injeção das dependências aqui
    var service = {
        adicionarBairro:    _adicionarBairro
        /**
         * Adicione aqui somente as funções que podem ser chamadas por um controller, ou um arquivo externo.
         * Se a função a ser chamada, for chamada dentro deste mesmo arquivo, não há necessidade de definir aqui
         */
    };
    return service;

    function _adicionarBairro(bairro, cidade, valor) {
        //Toda a lógica para adicionar o bairro vai aqui;
    };

    function carregarBairros(id_frete, id_cidade) {
        //Toda a lógica para carregar o bairro vai aqui;
    };
});

In this way, you can call the services of any controller, just inject the factory as dependency and make the request, so:

meuModulo.controller('Controller1',function($scope,factoryBairro,...){

And inside the controller call the function inside the Factory:

$scope.validaForm = function (bairro, cidade) {
    var valor = $("#valor").val();
    if ( /*verificações aqui*/ ) {
        if ($scope.alterar === false) {
            factoryBairro.adicionarBairro(bairro, cidade, valor); //Aqui você chama o serviço
        } else {
            //Restante do código

This will call the function adicionarBairro() which is inside Factory, it will run $http, do the checks, etc.. And when you call the function of loading the neighborhoods, just call the function, no mystery:

function adicionarBairro() {
    //Código anterior
    if (data < 1) {
        $http.post(url_sistema //.. restante do código
        //Mais código aqui

        //Substitua isso:
        Scopes.get('mostrarCidadesCtrl').carregarBairros(valor, cidade);

        //Por isso:
        carregarBairros(valor, cidade);

        //Restante do código
}
function carregarBairros(id_frete, id_cidade) {
    //Lógica da função aqui
}

So whenever you need to perform this function, inject Factory into the controller, and then call it.

I recommend that you look around and read a lot about it. It will GREATLY help your work, improve application performance, make your code cleaner and organized.


Edited:

To get a value created in a Factory inside a controller, so you can move to the view, just create a new function, example:

controller:

$scope.valor = factoryBairro.getData();

Factory:

var service = {
    adicionarBairro:    _adicionarBairro,
    getData:            _getData
};
return service;

var minhaData = 'Cidade';

function _getData() {
    return minhaData;
};

Obs.: If you want the object to sync between Factory and controller, e.g.: Updated Factory -> Automatically updates the controller. You must use the value to be passed within an array. Otherwise, the value will not be updated until the $digest spin.

At least I don’t know another method of synchronizing the data. If anyone knows, please share.

Synchronized example:

var minhaData = {
    'valor';
};

function _getData() {
    return minhaData;
};

function _setData() { //exemplo
    $http.get......
    return minhaData.valor = [
        {id: 1, cidade: 'São Paulo'},
        {id: 2, cidade: 'Rio de Janeiro'},
        //etc...
    ]
};

This way your controller is in sync, because you do not rewrite the whole object, only an internal value.

  • I will try here, any doubt put in the comments, thank you so far :)

  • Celsom, ta working super sure, just need one more piece of information, as I would to assign the variables I create in a Factory for the controller in use?

  • you can use one function equal to the others, just have one return to inform the value. I will update the response.

  • I think I understood, at the end of each answer, I apply a Return with the right variable?

  • how I would use these functions to present to me the return value in a view?

  • I think I’m looking kind of dumb, but as I reported above, I’m starting to tinker with angular now, if you can explain, thank you

  • See that the $scope.valor executes a function that returns to Scope the value assigned within Factory. Can you understand? If you are going to keep using this logic, I recommend that you read more about factory for it is extensive and difficult to explain here. Here is an excellent material!!!! See: https://www.youtube.com/playlist?list=PLQCmSnNFVYnTD5p2fR4EXmtlR6jQJMbPb

  • @Talesborn managed to solve?

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.