Desenvolvimento

21 mar, 2018

Usando decorator com firebaseArray e firebaseObject

Publicidade

Você sabe o que é um decorator?

Basicamente ele é utilizado para sobre escrever métodos antes que – de fato – o método original seja chamado! Vamos fazer um exemplo prático para entender melhor. Imagine o seguinte cenário:

Temos alguns endpoints que realizam operações de criação e update no banco de dados. Para cada um desses métodos, queremos salvar o dia da criação do registro e quem fez o cadastro, e o dia da alteração do registro e que fez o cadastro!

Usando MongoDB é muito fácil fazer isso, basta indicarmos 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 MongoDB incluirá os valores da data da criação e ou alteração! Mas no nosso caso, não estamos usando MongoDB e 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, pois 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 serviço tivermos que ficar colocando esse código, createdAt, createdBy, updatedAt, updatedBy, etc. O ideal é quando a gente chamar o $add ou $save – antes de executar o método – que ele inclua essas propriedades no nosso objeto data. É aí 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 fazemos a chamada do Service:

let data = {
  nome: 'Joao da Silva';
  idade: 33
}
Service.create(data);

Nosso service chama o firebaseArray, mas antes entra no decorator, que insere a data da criação e o nome do usuário logado no Firebase! E assim, a gente finaliza nossa tarefa.

Espero que ajude!