13/03/2018 Development / angular

Oque é um decorator?

Basicamente ele é utilizado para sobreescrever métodos antes que de fato o método original seja chamado!

Vamos imaginar o seguinte cenario:

Temos alguns endpoints que realizam Create e Update no banco. E para cada um desses métodos, eu quero salvar o dia da criacao do registro e quem fez o cadastro, e o dia da alteracao do registro e que fez o cadastro!

Usando MongoDB é muito facil fazer isso, basta a gente indicar no model um timestamp: true

Exemplo:

var clienteSchema = new mongoose.Schema({

nome: {type: String}

},{

    timestamps: true

});

Qualquer inclusão ou alteração que ocorrer, o mongo já incluirá os valores da data da criação e ou alteração!

Mas no nosso caso, não estamos usando MONGO e tambem queremos incluir a pessoa que fez a ação!

Voltando ao nosso cenário, criamos o nosso Service que receberá os dados e enviará para API.

Eu vou fazer bem básico, porque a intenção aqui é focar no decorator!!!

Service.create = (data)=> {

    data.createdAt = firebase.database.ServerValue.TIMESTAMP; // ou new Date().getTime()

    data.createdBy = firebase.auth().currentUser.displayName; // ou currentUser.uid;

  return this._$firebaseArray(firebase.database.ref('suaRefencia')).$add(data)  

}

 

Service.update = (id, data)=> {

    data.createdAt = firebase.database.ServerValue.TIMESTAMP; // ou new Date().getTime()

    data.createdBy = firebase.auth().currentUser.displayName; // ou currentUser.uid;

  return this._$firebaseObject(firebase.database.ref('suaRefencia').child(id)).$save(data)  

}

Olha que chato, se toda vez que a gente criar um servico, ter que ficar colocando esse código, createdAt, createdBy, updatedAt, updatedBy

O ideial é quando a gente chamar o $add ou $save, antes de executar o método, ele inclua essas propriedades no nsso objeto data.

É ai que entra o decorator!!!

let app = angular.module('app', []);

app.config(function($provide) {

    $provide.decorator('$firebaseArray', function($delegate, $window) {

        var _add = $delegate.prototype.$add;

        $delegate.prototype.$add = function (newData) {

            newData['createdAt'] = $window.firebase.database.ServerValue.TIMESTAMP;

            newData['createdBy'] = $window.firebase.auth().currentUser.displayName; //uid

 

            return _add.call(this, newData);

        };

        return $delegate;

    });

})

app.config(function($provide) {

    $provide.decorator('$firebaseObject', function($delegate, $window) {

        var _save = $delegate.prototype.$save;

        $delegate.prototype.$save = function () {

            this['updatedAt'] = $window.firebase.database.ServerValue.TIMESTAMP;

            this['updatedBy'] = $window.firebase.auth().currentUser.displayName;

            return _save.call(this);

        };

        return $delegate;

    });

})

Agora no nosso controller, a gente faz a chamada do Service

let data = {

  nome: 'Joao da Silva';

  idade: 33

}

Service.create(data);

Nosso service chamado o firebaseArray, mas antes entra no decorator, que insere a data da criacao e o nome do usuário logado no firebase!

E assim, a gente finaliza nossa tarefa.

Espero que ajude!