Archives pour la catégorie Javascript

Streams et Node.js : mongoose vers Amazon S3 ou fichier

Mongoose, ODM dont la réputation n’est plus à faire pour s’interfacer avec une base MongoDB, permet de lancer des requêtes sur des milliers de données, et de lire le résultat sous forme de stream.

Rapide rappel sur les Streams Node.js :

Il faut voir les Streams comme des entonnoirs : on peut les imbriquer comme des légos (grâce au pipe).

  • Certains permettent de lire : StreamReader, ils envoient l’eau
  • d’autres d’écrire : StreamWriter, ils récupère l’eau reçue
  • et d’autres sont les 2 à la fois : Duplex et/ou Transform, il reçoivent l’eau, peuvent la nettoyer (Transform) puis la renvoyer

L’entonnoir est imagine qui n’est pas anodine : si on verse de l’eau trop vite dans un entonnoir, elle s’accumule sans avoir le temps de passer. Le parallèle de ce phénomène avec les Streams est ce qu’on appelle la « back pressure« . C’est ce qui se passe le stream qui lit va plus vite que celui qui écrit.

Voyons ça dans un exemple…

Continuer la lecture de Streams et Node.js : mongoose vers Amazon S3 ou fichier 

Terminal : ouvrez vos onglets via un script bash

Travaillant sur une application SPA , j’ai besoin de démarrer mon environnement chaque matin.

j’ai donc besoin de 3 onglets :

  1. application serveur Node.js (node start)
  2. application cliente (gulp)
  3. Shell MongoDB

Voici donc un script permettant d’ouvrir 3 onglets de terminal et de lancer les commandes respectives dans chaque onglet :

Continuer la lecture de Terminal : ouvrez vos onglets via un script bash 

Validateur asynchrone avec Mongoose

Comment valider un champ de son modèle en asynchrone avant de l’enregistrer ?

Prenons le cas suivant : on a un modèle Mobilhomes et un modèle Marque.  On utilise mongoose pour enregistrer un mobilhome.

Ici, je n’utilise pas les ref dans le schéma, mais on pourrait le faire (cf http://mongoosejs.com/docs/populate.html).

var MobilHomeSchema = Schema({
  _id: Schema.Types.ObjectId,
  marque: {
    _id: Schema.Types.ObjectId,
    lib: String
  }
});

var MarqueSchema = Schema({
  _id: Schema.Types.ObjectId,
  lib: String
});

Le souci est que lorsqu’on enregistre un mobilhome avec un ID de marque « bidon », pour valider que l’ID existe bien et qu’un petit malin ne s’amuse pas à essayer d’enregistrer un ID bidon, on veut valider la donnée.

Il faut donc aller chercher dans la collection Marque, si l’ID existe ou non.

On a créé un validateur « custom » mongoose, qui se déclenche au validate(). Dans ce validateur, on fait un marque.findById(ID_A_VALIDER, callback) => ARGH ! on ne récupère le résultat du findById qu’en asynchrone, dans le callback, trop tard pour le validateur mongoose ! En gros, le validateur aurait besoin de savoir, en synchrone, si l’ID existe ou non….

var MobilHomeSchema = Schema({
  _id: {
      type: Schema.Types.ObjectId,
      validate: myCustomValidatorFunction
  marque: {
    _id: Schema.Types.ObjectId,
    lib: String
  }
});

function myCustomValidatorFunction(val){
   // supposons que Marque soit défini, que ce soit un modèle mongoose
   Marque.findById(val, function(err, item){
     if (err) handleError(err);

     // et là, qu'est-ce qu'on fait ?? on retourne TRUE ou FALSE ?
     // ben non... c'est trop tard...
     // 'suite' a déjà été affiché ! Vive l'asynchrone...

     // le code suivant ne sert évidemment à rien :(
     return (item != null);
   });

   console.log('suite');
}

La solution est donc, comme assez souvent avec l’asynchrone, que la librairie nous a prévu le coup ! Le custom validator peut attendre un second paramètre, qui est un callback que mongoose utilise pour traiter des validateurs asynchrones. Bon c’est écrit noir sur blanc dans la doc, mais ça mérite un petit exemple (http://mongoosejs.com/docs/api.html#schematype_SchemaType-validate) :

function myCustomValidatorFunction(val, respond){
   // supposons que Marque soit défini, que ce soit un modèle mongoose
   Marque.findById(val, function(err, item){
     if (err) handleError(err);

     // ici, on appelle le callback avec un booléen en paramètre, résultat de notre validateur
     respond(item != null);
   });
}

D’Angular.js à Backbone.js… le retour

Il y a quelques temps, j’avais écrit un article sur les frameworks JS clients, pour réaliser des applications mono-page (SPA).
Mon choix s’orientait alors plutôt vers Angular.js, après l’avoir testé, ainsi que Ember et Backbone.

Depuis la création de cette article, pas mal d’eau à couler sous le pont de mes essais, et j’avoue revenir vers Backbone.js finalement !

Pourquoi ?
Tout d’abord, entre temps j’avais réalisé mon propotype en Angular.js pour comparer. Seulement, bien que plus simple quand on commence (un certain nombre de choses fonctionnent sans avoir à les coder sois-même : binding des events entre vue et controlleur, etc.), on se rend compte petit à petit que c’est pas forcément le cas quand on dépasse le simple cas d’école, qu’il vaut mieux faire des directives plutôt que d’utiliser des composants natifs (comme pour bootstrap widgets par ex), qu’on est finalement pieds et poings liés au fonctionnement d’Angular. Backbone.js offre beaucoup plus de liberté, puisqu’il est très bas niveau. Il offre des briques avec lesquelles composer, mais finalement c’est toujours la même logique, très simple, bien qu’assez verbeuse.
De plus, en approfondissant le sujet, la verbosité de Backbone peut s’améliorer nettement en ajoutant une surcouche comme Marionette.js

De plus, autre argument non négligeable : Angular est une techno Google, soit disant open-source, mais la seule communauté travaillant sur ce dit  code est… Google ! Et les technos Google sont parfois éphémères.

Bon et pour finir, j’ai aussi été formé entre temps sur Node.js (par Christophe Porteneuve, allez-y les yeux fermés, c’est génialissime ! ), on a pu également échanger sur les frameworks JS pour les SPA, ce qui m’a aussi influencer dans mon choix de Backbone.js. Ca a nettement améliorer ma vision d’ensemble de comment articuler toutes ces briques : serveur, API REST, client, offline first, …

Je commence une application (une vraie, pas un proto cette fois !) en Node.js pour le côté serveur REST, et en Backbone.js/Marionette.js pour le côté client.
Je compte donc vous écrire un petit article là-dessus prochainement !

A bientôt  !

 

Installer Node.js via nvm (permet de le multi-versions)

Vous pouvez installer une version fixe de node, mais ça devient vite pénible de le mettre à jour, et si vous devez utiliser plusieurs versions selon les projets, n’en parlons pas…

Bref, nvm est là pour ça, il permet d’installer différentes versions et de basculer de l’une à l’autre par une simple ligne de commande.

Continuer la lecture de Installer Node.js via nvm (permet de le multi-versions) 

Animations AngularJS depuis la 1.2

AngularJS évolue vite. Les animations sont apparues il y a quelques temps pour combler un vide de cette fabuleuse librairie JS.
Bref, elles ont évoluées en 1.2 pour devenir plus simples : plus besoin d’attribut ng-animate.

Voici tout d’abord les ressources nécessaires pour trouver son bonheur en terme de documentation et d’exemples :

 

Personnellement, je cherchais comment afficher/masquer une carte, avec un effet de déroulé. J’ai galéré un moment avant de trouver qu’il fallait  animer sur la propriété CSS « max-height » et non « height » !

 

Choix d’un framework JS pour site mobile en single-page

Le site Web que je gère au quotidien repose sur Drupal. Pour faire une version mobile, la 1ère idée qui vient est simplement de faire un thème mobile et de continuer de se servir de Drupal pour desservir les pages. Mais je suis joueur, et j’avais envie depuis longtemps d’aller taquiner le JS de façon plus poussée, en faisant autre chose que du jQuery (Article très intéressant sur le sujet), étant une technologie de plus en plus utilisée, tant pour le mobile que pour des applications Web.

L’idée est donc naturellement venue de créer un site mobile « à part », appelant des Web-services Drupal qui retourneront le contenu (et seulement le contenu utilisé = perf). J’espère ainsi apprendre de nouvelle technologies, créer une application structurée, innovante, performante…

Continuer la lecture de Choix d’un framework JS pour site mobile en single-page 

PhoneGap : transformer votre single-page Web en une application mobile native

graphic_build_botC’est bien de ça qu’il s’agit. PhoneGap vous permet de créer une application/site en utilisant uniquement des technologies purement Web : HTML5, JS, CSS.
Votre application sera une page unique, comme par exemple avec jQueryMobile. C’est alors le JS qui s’occupe du routing entre « pages », qui ne sont que des chargements Ajax ou autres pour basculer d’un affichage à l’autre, et non plus des appels à des URLs côté serveur (en tous cas pas directement. S’il y a des appels à des URLs serveurs, c’est en JS, via Ajax ou autre sockets).

PhoneGap vous permet d’aller plus loin que de simplement embarquer votre site web. Il ajoute une librairie/API JavaScript, permettant d’interragir avec les fonctionnalités du téléphone, dans la mesure du possible (géolocalisation, notifications, GPS, caméra, contacts, etc.) : http://docs.phonegap.com/en/3.0.0/index.html

 

Voici les ressources que j’ai pu trouver sur le sujet, lorsque j’ai testé PhoneGap en créant une petite application.