Las cookies nos permiten ofrecer nuestros servicios. Al utilizar nuestros servicios, aceptas el uso que hacemos de las cookies. Más Información. Aceptar

Tutorial Meteor JS: Crear metodos de Publicación

Esaú A.
  • Escrito por Esaú A. el 18 de Abril de 2016
  • 5 min de lectura | tutorial
Tutorial Meteor JS: Crear metodos de Publicación

Vamos hoy con el último paso en nuestro tutorial en el que nos encargaremos de las suscripciones y las publicaciones.>

En las librerías del núcleo de Meteor encontramos DDP (Distributed Data Protocol), que no es más que un protocolo encargado de la actualización de datos en vivo, lo cual nos viene que ni pintado para nuestra aplicación, puesto que sigue un patrón de publicación y suscripción. Con esto, si generamos un mensaje, se notificará a nuestros suscriptores de dicho cambio en lugar de ser éstos últimos los que tengan que estar pendientes de si realizamos alguna publicación.>

Publicación/Suscripción de Twitts

Comprobemos cómo tendríamos acceso a los twitts desde el lado del cliente si tenemos el paquete autopublish desactivo.

Nano server/js/publications.js
Meteor.publish('tweets', function() {  
  return Tweets.find();
});
Nano client/js/tweetFeed.js
Template.tweetFeed.onCreated(function() {  
  this.subscribe('tweets');
});

Como vemos, el servidor está publicando todos los twitts que almacena y los usuarios se suscriben a éstos dentro de la plantilla definida. El problema llegados a este punto es que los clientes recibirán todos los twitts que publique el servidor y no sólo aquellos de los usuarios a los que esté siguiendo.

Pero podemos modificar levemente el código anterior para filtrar y mostrar los mensajes en función de unos parámetros determinados, como por ejemplo el autor de éstos.

Nano server/js/publications.js
Meteor.publish('tweets', function() {  
  if (this.userId) {
    var username = Meteor.users.findOne({_id: this.userId}).username;
    var currentFollowings = UserUtils.findFollowings(username);

    return Tweets.find({user: { $in: currentFollowings }});
  }
});

Mostrar twitts

Llegamos a un apartado importante, ya que ha causado revuelo en la red social que estamos referenciando en este tutorial. Cómo mostrar los twitts . Hace poco se anunciaba un cambio en los timeline de Twitter en el que los mensajes que mostrarían en función de la popularidad de los autores en lugar aparecer en orden cronológico inverso.

Pues bien, prosigamos con la línea clásica de esta red social de microbloging y situemos los twitts más recientes en lo alto del timeline. Para esto deberemos modificar el fichero tweetBox.js en el servidor.

Nano server/js/tweetBox.js
insertTweet: function(tweet) {  
  if (Meteor.user()) {
    Tweets.insert({
      message: tweet,
      user: Meteor.user().username,
      timestamp: new Date()
    });
  }
}

Con esto podremos cambiar el orden de los twitts directamente desde la solicitud de la suscripción, pero vayamos un paso más allá y determinemos cuántos twitts deberá cargar por defecto. Añadiremos las siguientes modificaciones y archivos:

Nano client/stylesheets/miTwitter.css
/* CSS declarations go here */
.tweetbox-container {
  margin: 30px;
  margin-left: 10px;
}

.tweetbox,.userBox {
  background-color: rgb(240, 247, 254);
}

.tweetbox .btnGroup {
  margin-top: 10px;
  display: flex;
  align-items: center;
}

.tweetbox .charCount {
  margin-right: 10px;
  color: gray;
}

.tweetbox .errCharCount {
  margin-right: 10px;
  color: red;
}

.user-container {
  margin-top: 30px;
  margin-left: 30px;
}

.user-container h4 {
  color: gray;
}

.user-container .table {
  margin-top: 10px;
}

.user-container .table th, .table td {
   border-top: none;
}

.user-container .tableHeader {
  color: gray;
}

.user-container .tableContent {
  color: rgb(117, 187, 251);
  font-size: 150%;
}

.user-container .fullbutton {
  width: 100%;
}

.user-container .input-sm {
  margin-bottom: 5px;
}

.user-container .login {
  margin-bottom: 15px;
}

.followBox {
  background-color: rgb(240, 247, 254);
}

.follow-container {
  margin-top: 30px;
  margin-left: 30px;
}

.follow-container .found-user {
  margin-top: 15px;
  display: flex;
  align-items: center;
}

.follow-container h5 {
  color: gray;
}

.tweetfeed {
  background-color: rgb(240, 247, 254);
}

.tweetfeed-container {
  margin: 30px;
  margin-left: 10px;
}
Nano client/js/tweetFeed.js
Template.tweetFeed.helpers({  
  'tweetMessage': function() {
    return Tweets.find({}, { 
        sort: {timestamp: -1}, 
        limit: 10
    });
  }
});
Nano client/templates/tweetFeed.html
<template name="tweetFeed">  
  <div class="tweetfeed-container">
    <div class="panel panel-default tweetfeed">
      <div class="panel-body">
        <!-- Texto para el contenido del Twitt -->
        {{#each tweetMessage}}
          <div class="panel panel-info">
            <div class="panel-heading">
              <h3 class="panel-title">@{{this.user}} 
                <span class="glyphicon glyphicon-triangle-right" aria-hidden="true"></span>
                 {{this.timestamp}}
               </h3>
            </div>
            <div class="panel-body">
              {{this.message}}
            </div>
          </div>
        {{/each}}
      </div>
    </div>
  </div>
</template> 

Ahora ya seríamos capaces de ver actualizaciones de mensajes del timeline en tiempo real.

Publicaciones Reactivas

De acuerdo, ya tenemos creado el sistema de usuarios que queríamos, pero si nos fijamos un poco, al seguir a un usuario nuevo sus publicaciones no nos aparecerán inmediatamente en nuestro timeline hasta que no volvamos a iniciar sesión. Esto es debido a que el método definido en el servidor sólo va a servir a los clientes aquello cargado en el cursor de la base de datos en el momento en que accedemos a ella en el inicio de sesión, y todos los cambios en las dependencias del cursor no se verán reflejados hasta volver a entrar en el sistema.

Esto tiene solución gracias de nuevo a la cantidad de recursos que Meteor pone a nuestra disposición, así que dentro de nuestra carpeta del proyecto escribiremos:

meteor add reywood:publish-composite 

Y completamos con estos bloques de código los siguientes archivos:

Nano server/js/publications.js
Meteor.publishComposite('tweets', function(username) {  
  return {
    find: function() {
      // Comprobar los usuarios a los que se está siguiendo
      return Relationships.find({ follower: username });
    },
    children: [{
      find: function(relationship) {
        // Encontrar mensajes de los usuarios que se siguen
        return Tweets.find({user: relationship.following});
      }
    }]
  }
});

Meteor.publish('ownTweets', function(username) {  
  return Tweets.find({user: username});
});

Como vemos, acabamos de definir el método Meteor.publishComposite() al que añadimos una función find: function() que se encargará de vigilar los cambios en la base de datos “relationships”, que serán pasados a cada función find: function() de cada hijo en este método. Éstos a su vez generarán solicitudes para obtener todos los twitts de cada usuario que se les haya pasado para así obtener una lista actualizada a cada momento.

Pero además también queremos que se muestren los mensajes del usuario que se encuentra registrado, y es por esto por lo que definimos el método Meteor.publish(‘ownTweets’, function(username)) , con el que además de los mensajes de los usuarios a quienes seguimos, podremos ver los nuestros propios.

Nano client/js/tweetFeed.js
Template.tweetFeed.onCreated(function() {  
  if (Meteor.user()) {
    this.subscribe('tweets', Meteor.user().username);
    this.subscribe('ownTweets', Meteor.user().username);
  }
});

Añadiendo esta línea a nuestro archivo tweetFeed.js en el lado del cliente, nos acabamos de suscribir a nuestros propios mensajes, para que lo que hemos definido en el archivo anterior tenga total funcionalidad.

Uso del método Publicación/Suscripción en las recomendaciones de usuario.

Ahora que sabemos cómo realizar publicaciones y suscripciones podemos mejorar nuestro sistema de recomendaciones de usuarios a seguir. Crearemos una lista de usuarios sugeridos para seguir, en la que al pulsar sobre ellos los añadiremos a nuestra lista de “siguiendo” y éste desaparecerá de dicha lista dando paso a otra recomendación.

Esto lo podemos hacer en el lado del cliente en lugar de en el servidor, dado que no hay involucrados datos que haya que ocultar a los usuarios. Todo lo que necesitamos es una lista de nombres de usuarios, y aquellos que ya sigue el usuario registrado.

Nano server/js/publications.js
// Lista de todos los usuarios
Meteor.publish('users', function(username) {  
  return Meteor.users.find({}, {
    fields: { 'username': 1 },
    limit: 100
  });
});

// Lista de usuarios seguidos por el usuario
Meteor.publish('followings', function(username) {  
  return Relationships.find({ follower: username });
});

Con esto el usuario ya dispone de las dos bases de datos que necesita para recibir las sugerencias sin duplicados en ellas.

Nano client/js/followUsers.js
Template.followUsers.helpers({  
  'recommendedUsers': function() {
    if (Meteor.user()) {
      var currentFollowings = UserUtils.findFollowings(Meteor.user().username);

      var recUsers = Meteor.users.find({
        username: {
          $nin: currentFollowings
        }
      }, {
        fields: { 'username': 1 },
        limit: 5
      }).fetch();

      return recUsers;
    }
  }
});

Template.followUsers.onCreated(function() {  
  if (Meteor.user()) {
    this.subscribe('users', Meteor.user().username)
    this.subscribe('followings', Meteor.user().username);
  }
});

Y una vez más queda demostrada la versatilidad de Meteor, gracias a la cual no necesitaremos modificar una sola línea de código en los ficheros del lado del servidor para que estos cambios funcionen correctamente en el cliente.

Uso de Publicación/Suscripción en el perfil del usuario

Vamos con los últimos cambios a realizar relacionados con las publicaciones y suscripciones. A estas alturas podemos ver cómo nuestro perfil no muestra ninguna información actualizada más allá del nombre de usuario. Vamos a solucionar esto, ya que en la red social en la que nos fijamos sí que podemos ver el número de twitts que hemos publicado, los seguidores de nuestro perfil, etc… e implementar esto no será en absoluto complicado.

Necesitaremos publicar otro conjunto de información con el que obtener el contador de seguidores:

Nano server/js/publications.js
Meteor.publish('followers', function(username) {  
  return Relationships.find({ following: username });
});

A continuación en la plantilla cliente usaremos el método count() de MongoDB para obtener el número de seguidores, de usuarios a los que sigue este usuario y los twitts que ha publicado:

Nano client/js/userManagement.js
Template.userManagement.helpers({  
  'tweets': function() {
    if (Meteor.user()) {
      return Tweets.find({ user: Meteor.user().username }).count();
    }
  },

  'following': function() {
    if (Meteor.user()) {
      return Relationships.find({ follower: Meteor.user().username }).count();
    }
  },

  'followers': function() {
    if (Meteor.user()) {
      return Relationships.find({ following: Meteor.user().username }).count();
    }
  }
});

Template.followUsers.onCreated( function() {  
  if (Meteor.user()) {
    this.subscribe('followings', Meteor.user().username);
    this.subscribe('followers', Meteor.user().username);
    this.subscribe('tweets', Meteor.user().username);
  }
});
Nano client/templates/userManagement.html
{{# if currentUser}}
<!—Mensaje para el usuario registrado -->  
<p>Hola <strong>@{{currentUser.username}}</strong>, bienvenido a tuTwitter en miTwitter</p>  
<button type="button" class="btn btn-info fullbutton" id="logout">Salir</button>

<table class="table">  
  <tr>
    <td class="tableHeader">Twitts</td>
    <td class="tableHeader">Siguiendo</td>
    <td class="tableHeader">Seguidores</td>
  </tr>
  <tr>
    <td class="tableContent">{{tweets}}</td>
    <td class="tableContent">{{following}}</td>
    <td class="tableContent">{{followers}}</td>
  </tr>
</table>

{{else}}

Y con esto ya podremos ver cómo nuestro timeline y estadísticas se actualizan en tiempo real gracias a la efectividad de Meteor. Aquí un ejemplo de cómo quedaría la interfaz, creando tres usuarios (@Openwebinars, @Toushiro y @Zaraki) dos de ellos se están siguiendo entre sí, por lo que verían sus mensajes mientras que @Zaraki no podría. No obstante vemos cómo en las recomendaciones a todos los usuarios le aparecerán aquellos que no estén siguiendo, por lo que sólo faltaría comenzar a publicar mensajes ;)

Imagen 0 en Tutorial Meteor JS: Crear metodos de Publicación

Os dejo una captura de cómo debería quedar nuestro árbol de directorios así como un enlace a la estructura de la aplicación al finalizar este tutorial.

Imagen 1 en Tutorial Meteor JS: Crear metodos de Publicación

Enlace a la estructura de la aplicación .

Además cabe hacer mención a que no hace mucho tiempo, Meteor recibió un importante respaldo tanto económico como empresarial a fin de ampliar aún más sus posibilidades y evolucionar para ofrecer componentes actuales y de gran estabilidad.

No obstante, mientras sigue su curso, los usuarios y comunidades de desarrollo continúan aportando paquetes a su repositorio, los cuales podemos implementar en nuestros proyectos libremente, encontrando en la mayoría de las ocasiones módulos muy completos que nos ahorrarán el tener que desarrollarlos y por ende, horas de trabajo en la creación de nuestras web-apps.

Estas son algunas de las empresas que ya confían en OpenWebinars

Profesores y profesionales

Nuestros docentes son profesionales que trabajan día a día en la materia que imparten

Conviértete en profesor de OpenWebinars