Frameworks

Tutorial Meteor JS: Métodos de Servidor

Proseguimos con el desarrollo de nuestro clon de Twiiter a la que hoy añadiremos algunos métodos del lado del servidor, que nos permitirán buscar y seguir a otros usuarios de esta aplicación.

Publicado el 11 de Abril de 2016
Compartir

Proseguimos con el desarrollo de nuestro clon de Twiiter a la que hoy añadiremos algunos métodos del lado del servidor , que nos permitirán buscar y seguir a otros usuarios de esta aplicación.

Para este fin construiremos un módulo de búsqueda que nos permitirá interactuar con el servidor, y todo con la mínima cantidad de líneas de código ;) al estilo Meteor.

 

Búsqueda de un usuario

Tal y como dejamos la app en la anterior publicación de este tutorial, el lado del cliente ha dejado de tener acceso a los usuarios debido a que por seguridad, deshabilitamos el módulo de Meteor llamado autopublish . Así que comencemos a crear el módulo de búsqueda.

En el archivo miTwitter.css dentro de /client/stylesheets añadimos el siguiente código para ir dando forma a este formulario de búsqueda:

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 .fullbutton {
  width: 100%;

}

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

}

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

}

Pasamos a continuación a generar la visualización del módulo en el html, para lo que creamos el siguiente fichero:

Nano /client/templates/followUsers.html

Y añadimos este código de formulario:


<form class="form-inline"> 

  <input type="text" class="form-control" id="searchUser" placeholder="Search for user">

  <button type="submit" class="btn btn-info">Search</button>

</form> 

Para terminar creamos el siguiente archivo en la carpeta js:

Nano client/js/followUsers.js

Y dentro colocamos estas líneas de código:


Template.followUsers.events({ 

  'submit form': function(event) {

    var searchUser = event.target.searchUser.value;

 

    var foundUser = Meteor.call('findUser', searchUser, function(err, res) {

      if (res) Session.set('foundUser', res);

    });

    return false;

  }

});

Elegimos usar un formulario en lugar de un cuadro de texto con botón de búsqueda porque así tenemos la ventaja de la función submit form , que puede aceptar un event variable en función de los campos contenidos en el formulario. Podremos acceder al valor en ese momento en el cuadro de texto mediante event.target.searchUser.value .

Aquí es donde usaremos Meteor.call(‘findUser’, searchUser, callback) . No os preocupéis si no os suena de momento, ya que aún no hemos definido el método findUser aún. Esto lo haremos en el lado del servidor, que es la vía mediante la que Meteor muestra información del servidor al cliente, mediante llamadas.

searchUser será la primera variable y el primer parámetro en llegar al método del servidor, que también contendrá un callback o devolución de resultado cuando la solicitud se haya completado.

Por último terminamos con un return false debido a que el formulario por defecto solicitará el refresco de página al mostrar los resultados, y queremos evitar que eso pase.

Vamos entonces al lado del servidor y definimos este método:

Mkdir server

Mkdir server/js

Nano server/js/followUsers.js

Y dentro de este archivo añadimos estas líneas:

Meteor.methods({ 

  'findUser': function(username) {

    return Meteor.users.findOne({

      username: username

    }, {

      fields: { 'username': 1 }

    });

  }

});

El método findUser está definido y será ejecutado únicamente en el servidor al estar el archivo que hemos creado dentro de la carpeta /server en nuestra estructura de aplicación. Como vemos este método no consta más que de una llamada a la base de datos MongoDB para encontrar un nombre de usuario, mediante el argumento username pasado desde Meteor.call(‘findUser’, searchUser) del cliente.

A estas alturas podemos apreciar la simplicidad de Meteor, encargándose éste de ejecutar cada método o función en el lado que corresponda según la estructura que le hayamos especificado.

Mostrar usuario encontrado

Ya que hemos definido todo el sistema de llamada al servidor, la base de datos, etc… tendremos que mostrar los resultados de alguna forma, así que vamos modificando algunos archivos:

Nano client/templates/followUsers.html
{{#if foundUser}}

  <div class="found-user">

    <button type="button" class="btn btn-default" id="follow">Follow @{{foundUser.username}}</button>

  </div>

{{/if}}
Nano client/js/followUsers.js
Template.followUsers.helpers({ 

  'foundUser': function() {

    return Session.get('foundUser');

  }

});

Template.followUsers.events({ 

  'click #follow': function() {

    Meteor.call('followUser', Session.get('foundUser').username);

  }

});
Nano server/js/followUsers.js
Meteor.methods({ 

  'followUser': function(username) {

    Relationships.insert({

      follower: Meteor.user().username,

      following: username

    });

  }

});

Como vemos, de nuevo estamos llamando a un método definido en el servidor directamente desde el cliente, Meteor.call(‘followUser’, Session.get(‘foundUser’).username) .

Si en los resultados el usuario encuentra a alguien que le gustaría seguir, también estamos definiendo un botón para facilitarle tal cosa. Además en el lado del servidor, estamos creando una nueva base de datos para almacenar las diferentes relaciones entre seguidores y seguidos, por lo que nos interesaría definir un sistema mediante el cual un usuario no pueda seguir dos veces a otro y que las estadísticas (que tanto preocupan a muchos) se vean alteradas.

Esto podemos hacerlo a través de una simple comprobación en MongoDB:

Nano server/js/startup.js

Meteor.startup(function () { 

  Relationships._ensureIndex({follower: 1, following: 1}, {unique: 1});

});

La función Meteor.startup() se ejecutará cuando se inicie el servidor asegurándonos que todo está actualizado cuando el usuario realiza el inicio de sesión. ensuerIndex es una operación de MongoDB para crear y asegurar la singularidad de los valores (con lo que evitamos lo que decíamos anteriormente).

Recomendar usuarios a seguir

Vamos a mostrarles a los usuarios de nuestra app una serie de otros usuarios aleatorios a los que poder seguir. Esto podremos realizarlo gracias a un módulo que vamos a constituir con la modificación de los siguientes ficheros:

Nano client/templates/followUsers.html
<div class="recommend-users"> 

  <h5>Who to follow:</h5>

  {{#each recommendedUsers}}

    <button type="button" class="btn btn-default" id="followRec">Follow @{{this.username}}</button>

  {{/each}}

</div>
Nano client/js/followUsers.js
Template.followUsers.helpers({ 

  'recommendedUsers': function() {

    return Session.get('recommendedUsers');

  }

});


Template.followUsers.events({ 

  'click #followRec': function(event) {

    Meteor.call('followUser', this.username);

  }

});
 

Template.followUsers.onRendered(function () { 

  Meteor.call('recommendUsers', function(err, res) {

    Session.set('recommendedUsers', res);

  });

});

Desde el lado del cliente se hace una llamada al método del servidor recommendUsers a fin de obtener un listado de candidatos a seguir. Si el usuario hace clic en alguna de las recomendaciones, la función 'click #followRec' será llamada se asignará la relación entre ambos usuarios.

El método recommendUsers se define en el servidor, así que vamos con él:

Nano server/js/followUsers.js

Meteor.methods({ 

  'recommendUsers': 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;

    }

  }

});

Como no queremos recomendar usuarios que ya se están siguiendo, llamamos al método UserUtils.findFollowings(Meteor.user().username) para encontrar y descartar los que ya se estén siguiendo. Este método lo definiremos en el directorio /lib para que esté accesible tanto por parte del servidor como del cliente.

Nano lib/userUtils.js

UserUtils = function() {};    //no var in front

UserUtils.findFollowings = function(username) { 

  var currentFollowings = Relationships.find({

    follower: username

  }).fetch().map(function(data) {

    return data.following;

  });

  currentFollowings.push(Meteor.user().username);

 

  return currentFollowings;

};	

Pasar la inserción de Twitts al servidor

Desde que retiramos el paquete insecure de nuestra app en Meteor (recodad el capítulo anterior de este tutorial) no podemos registrar ningún nuevo twitt en la base de datos desde el lado del cliente, así que nos interesa pasarlo al lado del servidor mediante la modificación de estos archivos:

Nano client/js/tweetBox.js

'click button': function() { 

  var tweet = $('#tweetText').val();

  $('#tweetText').val("");

  Session.set('numChars', 0);

  Meteor.call('insertTweet', tweet);

}
Nano server/js/tweetBox.js

Meteor.methods({ 

  insertTweet: function(tweet) {

    if (Meteor.user()) {

      Tweets.insert({

        message: tweet,

        user: Meteor.user().username

      });

    }

  }

});

Y con esto ya tendremos nuestros métodos de servidor configurados y funcionando, listas de usuarios recomendados para seguir y un formulario de búsqueda. Como hemos visto hasta ahora, la sencillez de Meteor hace que con unas cuantas líneas de código tengamos una app de cierta complejidad funcionando en unos cuantos y sencillos pasos.

Os dejo un enlace a la estructura de archivos y a los mismos según quedaría la aplicación a día de hoy. Recordad suscribiros y seguirnos en las redes sociales, así como echar un vistazo al catálogo de cursos de Openwebinars, donde seguro que más de uno de los disponibles llama vuestra atención, ya que son impartidos por profesionales de amplia experiencia y siempre orientados a lo más solicitado en el mundo laboral. Un saludo!

Estructura de la APP

Estrcutura de App


Compartir este post

También te puede interesar...

Tecnología

Tutorial Meteor JS: Interfaz de Registro e inicio de sesión

30 Marzo 2016 Esaú Abril Nuñez
Tecnología

Tutorial Meteor JS

06 Marzo 2016 Esaú Abril Nuñez
Artículos
Ver todos