Sebastian Gomez
🌟 Implementando map como Operador en Observables 🌟
En este post, vamos a explorar cómo aumentar el número de operadores que podemos implementar y usar dentro de un Observable 📈. Primero, recordemos cuál es la definición más pura de un observable con una función generadora de observables a partir de eventos:
// Define la clase "Observable"
class Observable {
// Constructor de la clase "Observable" que acepta un argumento "subscribe"
constructor(subscribe) {
// Asigna el valor del argumento "subscribe" a la propiedad "_subscribe" del objeto
this._subscribe = subscribe;
}
// Método "subscribe" que acepta un objeto "observer"
subscribe(observer) {
// Llama a la función almacenada en la propiedad "_subscribe" y le pasa el objeto "observer"
return this._subscribe(observer);
}
// Define un método estático "fromEvent" que acepta dos argumentos: "domElement" y "eventName"
static fromEvent(domElement, eventName) {
// Retorna una nueva instancia de la clase "Observable"
return new Observable(function subscribe(observer) {
// Define una función "handler" que acepta un argumento "ev"
const handler = (ev) => {
// Llama al método "next" del objeto "observer" y le pasa el argumento "ev"
observer.next(ev);
};
// Añade un event listener al elemento DOM "domElement" que escucha el evento especificado en "eventName" y llama a la función "handler" cuando el evento ocurre
domElement.addEventListener(eventName, handler);
// Retorna un objeto que contiene un método "unsubscribe"
return {
// Define el método "unsubscribe"
unsubscribe() {
// Elimina el event listener del elemento DOM "domElement" asociado con el evento "eventName" y la función "handler"
domElement.removeEventListener(eventName, handler);
},
};
});
}
}
Creando Observables que devuelven información del evento de la siguiente manera:
const button = document.getElementById("button");
const clicks = Observable.fromEvent(button, "click");
const clicksSubscription = clicks.subscribe({
next(e) {
console.log("Click in the button", e); // “e” contiene toda la información del evento
}
});
clicksSubscription.unsubscribe(); // De esta manera te puedes des-suscribir
Ahora, imaginemos que queremos hacer más operaciones sobre la cadena de datos, como obtener sólo algunos datos del evento o escuchar solo los clicks que se hagan en la parte izquierda del botón 🎯. Vamos a implementar la función map sobre observables.
La función map es una función pura que itera sobre cada elemento de un array y "mapea" cada ítem de un array en otro:
[1, 2, 3].map(elemento => elemento * 2); // Retorna [2, 4, 6]
Para implementar map en observables, haremos lo siguiente:
class Observable {
...
map(projection) {
const self = this;
return new Observable(function subscribe(observer) {
const subscription = self.subscribe({
next(v) {
let value;
try {
value = projection(v);
observer.next(value);
}
catch(e) {
observer.error(e);
subscription.unsubscribe();
}
},
error (e) {
observer.error(e);
},
complete () {
observer.complete();
}
});
return subscription;
});
}
...
}
Y ahora, podemos usar map para transformar los datos dentro de nuestro observable, obteniendo solamente la posición del mouse en el momento que hizo click sobre el botón 🖱️.
const button = document.getElementById("button");
const clicks = Observable.fromEvent(button, "click");
const clicksSubscription = clicks
.map((ev) => ev.offsetX)
.subscribe({
next(offSetX) {
console.log(offSetX);
},
});
Echa un vistazo al siguiente Codepen para revisar la definición completa: Codepen
💡 Conclusiones:
🏋️♂️ Ejercicios para practicar:
🔖 Resumen de 3 puntos:
¡Excelente! Espero que este post te haya sido útil y te haya ayudado a comprender cómo implementar el operador map en Observables. Si tienes alguna pregunta o comentario, no dudes en dejarlo en la sección de comentarios. ¡Buena suerte en tus proyectos y no olvides seguir aprendiendo y practicando! 🚀
Si te gustó este post, no olvides compartirlo con tus amigos y colegas a través de las redes sociales utilizando los enlaces proporcionados. ¡Hasta la próxima!
Creador de contenido principalmente acerca de tecnología.