Archives de catégorie : Web

Angular/Ionic: simuler un serveur avec des fichiers JSON

Je travaille actuellement sur un projet mobile Ionic et j’ai du mettre en place un mode démonstration avec des données fake. Au lieu de faire un appel au serveur, j’utilise des fichiers JSON qui contiennent les données à retourner.

Cela peut également être pratique si vous devez travailler sans être dépendant de la partie serveur.
Afin d’éviter de toucher le code métier (mes services angular) et faire des tests dans mes controllers/services pour savoir si je suis en mode démo ou pas, j’utilise un interceptor angular (la documentation angular sur $http et les interceptors) qui va faire la requête http ou renvoyer les bonnes de démonstration.

L’astuce ici consiste à contourner le cache de $http. Il faut modifier dans la fonction request de l’interceptor l’objet config pour définir une fonction get dans le cache. (Seulement les verbes HTTP GET et JSONP peuvent utiliser le cache $http. Je force un appel en GET mais garde en mémoire la méthode d’origine). Ainsi, l’appel serveur ne sera pas fait et la fonction définie en tant que cache sera appelée. Vous pouvez ainsi retourner vos données, dans notre cas à partir de fichiers json.

Voici le code de mon interceptor:

(function (module) {
  'use strict';
  module.factory('demoInjector', ['baseUrl', '$injector', function(baseUrl, $injector) {

    //check if request is done on backend and not templates for example 
    const isBackendRequest = function (config) {
      return config.url.indexOf(baseUrl) > -1;
    };

    var sessionInjector = {
      request: function(config) {
        if (!isBackendRequest(config)) {
          return config;
        }
        const demoService = $injector.get('DemoService');
        if (demoService.isDemoMode) {
          //store http method and change request method to GET because only GET and JSONP are cached
          config.originalMethod = config.method;
          config.method = 'GET';
          config.cache = {
            get: function() {
              return demoService.mock(config);
            }
          };
        }
        return config;
      }
    };
    return sessionInjector;
  }]);

  module.config(['$httpProvider', function($httpProvider) {
    $httpProvider.interceptors.unshift('demoInjector');
  }]);
})(angular.module('diagral'));

Dans le demoService, service qui contient la logique du mode démonstration, on se base sur l’url (via une RegExp) et la méthode HTTP (sauvegardée dans la propriété originalMethod via l’interceptor) de l’objet config pour déterminer le contenu approprié.

Voyons maintenant comment charger un fichier JSON inclus dans votre projet Ionic (en version 1). Pour ma part, les fichiers sont stockés dans /www/demo.
Sous Android, le dossier www est placé dans le dossier android_asset. Il faut donc adapter l’url du fichier cible en prenant compte de la platform cible via ionic.Platform. Il suffit ensuite de faire une requête via $http avec le chemin du fichier.

Les exemples ci-dessous sont en ES2015 avec des classes (d’où les this …)

this.url = '';
if (ionic.Platform.isWebView() && ionic.Platform.isAndroid()) {
    this.url = '/android_asset/www/';
}

this.$http.get(this.url + 'demo/myFile.json');

Afin de simuler un temps d’attente réaliste, vous pouvez utiliser $timeout.

const delay = 1000; //délai d'1 seconde
const responseDeferred = this.$q.defer();
this.$timeout(() => {
  this.$http.get(this.url + 'demo/myFile.json')
    .then(resp => responseDeferred.resolve(resp));
}, delay);
return responseDeferred.promise;

Il est également possible de renvoyer un objet JavaScript directement (si vous avez besoin de gérer un état par exemple). Il faut, dans ce cas, créer une réponse comme ceci:

const response = {
  config: config,
  status: 200,
  headers: () => {},
  data: () => angular.toJson({
          name: 'Julien',
          age: 35,
          lastUpdate: Date.now()
        })  
};

Voici le code final de la fonction mock qui utilise un tableau de configuration contenant les mocks avec la réponse attendue et les différentes options (délai, json/fonction, …).

mock(config) {
  const response = {
	config: config,
	status: 200
  };

  //Configuration du tableau des mocks
  const staticResponses = [
  {
    pattern: /login$/,
    jsonFile: 'login.json',
    method: 'POST'
  },
  {
    pattern: /article$/,
    data: () => this.getFakeArticles(),
    delay: 500
  },
  //...
  ];
  const staticResponse = this.findMock(staticResponses, config);
  if (staticResponse) {
    const r = this.$q.defer();
    const { delay = 200 } = staticResponse; //200ms by default if not defined
    this.$timeout(() => {
      if (staticResponse.jsonFile) {
        this.$http.get(this.url + 'demo/' + staticResponse.jsonFile)
          .then(resp => r.resolve(resp));
        return;
      }
      if (this._.isFunction(staticResponse.data)) {
        response.data = staticResponse.data(config.data, config.url);
        r.resolve(response);
        return;
      }
    }, delay);
    return r.promise;
  }

  response.status = 500;
  response.data = { message: 'Indisponible en mode démo'};
  return this.$q.reject(response);
}

findMock(staticResponses, { url: requestUrl, originalMethod: method}) {
  return this._.find(staticResponses, r => r.pattern.test(requestUrl) && method === (r.method || 'GET'));
}

Components en angular 1.5

Un des grands changement d’Angular 2 est l’abandon des controller pour l’utilisation de components. Afin de facilité la migration, la version 1.5 d’Angular a introduit une méthode component() permettant de créer des composants. Cette version introduit également les concepts de one-way data binding et de lifecycle hooks.

Création d’un component

La création d’un composant est très simple. il suffit de renvoyer un objet comme dans l’exemple ci dessous.

var ProductComponent = {
  bindings: {
    name: '=',
    price: '='
  },
  template: `Name: {{$ctrl.name}}
             Price: {{$ctrl.price}}`
};

angular
  .module('app', [])
  .component('productComponent', ProductComponent);
<product-component name="Nexus 5" qty="299"></product-component>

On peut voir dans l’exemple ci dessus:

  • la déclaration des bindings via la propriété … bindings. Nous les déclarons de la même façon que pour les directives. Les bindings sont automatiquement bindés sur le controller (bindToController dans angular 1.4)
  • la déclaration de notre template (j’utilise ici un template string ES6). Notez qu’il est possible d’utiliser un template via un fichier html via templateUrl (de la même façon que les directives).
  • Les components utilisent des controller en ‘controller as‘ dont le nom par défaut est $ctrl. Vous pouvez bien entendu le modifier via la propriété controllerAs

Nous voyons que dans le cas de composants d’affichage, les composants sont beaucoup plus simple et concis.

One way data bindings

Une des nouveautés très intéressante de Angular 1.5 est l’apparition du one way binding via la notation ‘<‘. Les changements effectués sur une propriété bindée en one-way ne seront pas répercutés sur l’objet sur lequel il est bindé (sens component -> parent). Les mises à jour sur l’objet source sont répercutées sur le component (parent -> component). On gagne ainsi en performance et en maintenance.

Lifecycle hooks

La version 1.5 introduit également une notion de cycle de vie des components sur lequel nous allons pouvoir nous plugger.
Nous avons les événements suivant sur lesquels nous allons pouvoir nous abonner:

  • onInit : à l’initialisation du component. Idéal pour initialiser notre composants, definir les valeurs par defauts, …
  • onChanges: à chaque modification de valeur d’un binding one-way.
  • onDestroy: lors de la destruction du composant. Idéal pour libérer les ressources …

Tests

Une des choses appréciables avec angular est la testabilité. Les components sont très simple à tester. Les tests d’un controller d’un component se feront via l’utilisation de $componentController inclut dans ngMock. L’avantage est qu’on n’a pas besoin de créer un élément.

Migration d’une directive vers un component

J’ai déjà parlé d’une directive gérant un select avec des valeur numérique. Voyons comment la migrer vers un composant.

Liens

Conclusion

L’arrivée des components dans la version 1.5 d’angular a modifié la façon de développer des applications angular 1.x. Je vous conseille vivement leur utilisation, qui plus est si vous souhaitez préparer la migration vers angular 2.

Chrome : Debug d’un site mobile

J’ai présenté dans un précédent article comment debuger à distance avec Chrome sous android.

La dernière version de Google Chrome permet  d’aller plus loin dans le debug d’application web mobile sous Chrome. (Il faut actuellement avoir Chrome beta pour android (rev32) pour avoir cette fonctionnalité).

  • Plus facile pour débugger à distance car le driver est inclus dans Chrome
  • Visualisation du contenu du mobile dans le navigateur via un émulateur. Possibilité d’interagir directement dans l’émulateur (Utilisation du clavier, sélection d’élément via l’inspecteur, …)
  • Émulation d’une configuration d’un terminal
  • Redirection de port (permet de faire pointer sur le terminal  localhost sur la machine de dev)

Je vous conseille la lecture de l’article de présentation sur html5rocks, le lien vers la page des chrome DevTools, et la vidéo de présentation :

Outils CSS3 – HTML5 – JavaScript : Episode 8

Html

  • Une liste d’articles sur l’utilisation d’Emmet(part 1, 2, 3 et 4) (mon article de présentation d’Emmet qui s’appelait à l’époque Zen coding) Toujours sur le même sujet, une cheat sheet de emmet assez complète.
  • Un article qui présente l’api de vibration
  • Responsinator : Permet de visualiser le rendu d’un site en mode responsive sur différents terminaux (iPhone 3/4, iPhone 5, iPad, Android, …) en portrait et paysage. Un exemple avec mon site.

CSS

  • Spinkit : Animations d’attente en CSS3
  • Myth : Myth is a preprocessor that lets you write pure CSS without having to worry about slow browser support, or even slow spec approval. It’s like a CSS polyfill.
  • CSS Zen Garden : La nouvelle version HTML5 Zen Garden.
  • lesshat.com : collection de mixins less
  • extractCSS : permet d’extraire les styles inlines d’un code HTML
  • Stitches : un générateur de Sprites
  • CSS Animate : Outil de génération d’animations CSS

JavaScript

Divers

Chrome : Bien débuger avec la barre d’outils # 2

Cet article fait suite à l’article Chrome : Bien débuger avec la barre d’outils.

Ajouter une Watch Expression

Lors de debug JavaScript, vous devez regarder dans vos objets pour surveiller l’évolution des valeurs de vos variables. Chrome permet de rajouter des expressions afin de plus facilement surveiller ces valeurs. Ces expressions sont gardées au rafraîchissement de la page.

Les Watch Expressions sont gérés dans l’onglet Sources, dans la partie droite, dans l’accordéon du même nom. L’ajout se fait en cliquant sur le +. Il suffit ensuite d’entrer l’expression dans la textbox qui propose l’auto-complétion. Les valeurs sont automatiquement mis en jour en debug et il est possible de les rafraîchir via l’icône de rechargement.

WatchExpression

Emuler les événements de touch

Aujourd’hui les tablettes et smartphones sont de plus en plus répandu et beaucoup les utilisent pour naviguer sur Internet. Sur ces appareils sans souris, ce sont des événements « touch » (avec les doigts) qui sont émis. Chrome permet d’émuler ces événements touch. Pour cela il faut aller dans la barre de développement de Chrome, aller dans les préférences (icône en bas à droite en forme d’engrenage), et aller dans Overrides et cocher la case Emulate touch events. Bien entendu, vous ne pourrez pas simuler plusieurs doigts mais c’est déjà ça !!

Emuler les événement touch

Emuler un User Agent et la résolution d’un appareil

Chaque navigateur peut être identifié par ce que l’on appelle un User Agent. Cette information est envoyée à chaque requête au serveur et contient notamment des informations concernant le nom de l’application, la version, le système d’exploitation, la langue, etc…

Il est ainsi possible de modifier la réponse en fonction des informations de l’User-Agent comme renvoyé une page spécifique pour les appareils mobile par exemple.

Chrome permet de modifier cet User-Agent. Pour cela, il faut ouvrir la barre de développement de Chrome, aller dans les préférences (icône en bas à droite en forme d’engrenage), et aller dans Overrides et cocher User Agent. Une liste des principaux navigateur et appareils sont pré-configurés (Firefox, IE, IPhone, IPad, Android, …)

Il est également possible de simuler une résolution (j’avais expliqué dans un post précédent comment le faire avec Firefox) encochant l’option Device metrics. On peut choisir une résolution de manière manuelle et définir le facteur de zoom (Font scale factor). Dans le cas d’un appareil mobile, la sélection d’un user agent met à jour automatiquement la configuration avec celle de l’appareil choisi. Super Pratique !!!!

Voici en exemple mon CV configuré pour un téléphone Android Nexus S.

Emuler un User-Agent et une résolution

Simuler une géolocalisation

Aujourd’hui, de plus en plus d’application utilise la géolocalisation pour offrir des résultats adaptés à notre localisation (ex : pages jaunes). Chrome permet de simuler une géolocalisation et une position non disponible.

Emuler une géolocalisation

Emuler un média CSS

CSS permet d’adapter le rendu suivant le média sur lequel est affiché le site (écrans, projecteurs, imprimante, tv, Synthèses vocales, …). Chrome permet d’émuler un média. Cela se fait toujours dans les préférences de Chrome, Overrides, cocher Emulate CSS media et sélectionner le média à cibler. Cela s’avère très pratique notamment dans le cas de l’impression (j’avais évoquer la gestion des liens lors de l’impression dans un précédent article). Ci dessous, l’exemple de mon CV via l’émulateur avec le média print :

Emuler le média print

Console.Table

Vous utilisez surement abusivement de console.log pour débuguer vos scripts. Console.table est une méthode qui permet d’afficher le résultat sous la forme d’un tableau. Cela est pratique pour visualiser les objets de types Arrays mais également les objets.

Console.Table

A noter, que console.table() est également disponible sous Firebug.

Voici un article complet de présentation de console.table().

Liens

Outils CSS3 – HTML5 – JavaScript : Episode 7

L’épisode 7 des outils liés aux technologies du web …

JavaScript

  • Une liste de plugins essentiels JQuery
  • jsdb.io : Un site qui répertorie les librairies JavaScript regroupés par thèmes avec recherche.
  • SnapSvg : une librairie pour gérer du SVG. Créée par Adobe (qui s’y connaît en vectoriel) en open-source, un des principaux développeurs est le concepteur de la librairie Raphael.js, une autre librairie qui permet de gérer du SVG.
  • Un article concernant la détection et l’avertissement lors d’une déconnexion d’un utilisateur
  • Normes de codage JS de airbnb (le site de réservation d’appartement entre particuliers)

CSS

  • Topcoat : une librairie CSS par adobe
  • Create CSS3 : Un générateur de règles CSS (assez complet, support des préfixes)
  • Koala : Une interface pour générer du CSS à partir de  LESS/SASS/Compass et du JavaScript à partir de CoffeeScript. Compatible Windows, Linux et Mac

HTML

  • Un très bon article sur sitepoint.com concernant la géolocalisation.
  • Real favicon generator : générateur de favicon (image représentant un site. Permet de générer également des icons pour Win 8, tablettes (iOS, Android, Windows Phone).
  • Ionicons : la police d’icône du framework ionic, pour créer des applications mobile en HTML5.
  • Runnable.com : permet de rechercher du code et de le tester (compatible avec pas mal de technos web (PHP, .NET, Ruby, NodeJs, …)
  • Une très bonne présentation (en anglais) sur l’automatisation de la partie front d’un projet
  • Un très bon article sur le Responsible Web design avec une boite à outils

Utilisation du cache ASP.NET dans un Web Service asmx

Une des méthodes pour améliorer les performances de son site web est l’utilisation du cache. Ce dernier permet de garder en mémoire des informations afin de ne pas les recalculer à chaque appel. L’utilité de l’objet cache est qu’il permet de définir une politique d’expiration, c’est à dire de définir combien de temps les données enregistrées dans le cache sont valides. Une fois cette durée expirée, la donnée sera supprimée du cache. Celle-ci sera recalculée à l’appel suivant.

Dans une page aspx, l’accès au cache se fait par l’appel à l’objet Cache. Dans un web service (asmx), il faut passer par le contexte Http : HttpContext.Current.Cache

HttpContext ctx = HttpContext.Current;
//Si la valeur est dans le cache on la renvoie
if (ctx.Cache["CachedData"] != null)
{
    return (CachedData)ctx.Cache["CachedData"];
}
//On récupère et on enregistre dans le cache avec une durée de rétention de 7 jours
CachedDataresult = DataManager.GetData();
ctx.Cache.Insert("CachedData", result, null, DateTime.Today.AddDays(7), TimeSpan.Zero);
return result;

Voici le lien vers la page MSDN

ASP.NET MVC : Présentation de T4MVC

Je viens de changer de boite et mon premier projet est un projet en ASP.NET MVC dans sa version 3. Je vais vous présenter un outil qui permet de faciliter le développement et la maintenance d’un application MVC : T4MVC.

Il s’agit d’un paquet (package) que l’on installe via NuGet, le gestionnaire de package de Visual Studio. Cet outil prend la forme d’un ficher T4 (Text Template Transformation Toolkit), T4MVC.tt, qui sera rajouté à votre projet. Les fichiers T4 permettent de la génération de code.

Dans ASP.NET MVC, dans de nombreux cas, les méthodes prennent en paramètre des chaines de caractères (« magic strings ») où il est facile de se tromper. L’utilisation de T4MVC permet de résoudre ce problème en générant des constantes, des méthodes pouvant prendre en paramètre des expressions lambda afin de réduire les erreurs et leur temps de détection. En effet, avec l’utilisation de chaîne de caractères, une erreur ne sera visible qu’à l’exécution alors qu’en utilisant T4MVC, vos erreurs seront remontées à la compilation.

Installation

Pour l’exemple, j’ai créeé un nouveau projet ASP.NET MVC en ayant sélectionné le template Internet Application.

L’installation de T4MVC se fait via le gestionnaire de paquet NuGet de Visual Studio. Nous allons ici utiliser l’interface graphique mais il est bien évidemment possible de l’installer par la console NuGet. Le lancement du gestionnaire NuGet se fait via un clic droit sur le projet MVC puis Manage NuGet Packages ….

Lancement du gestionnaire de paquet NuGet

Il faut ensuite sélectionner l’onglet Online et effectuer une recherche sur T4MVC et cliquer sur Install.

NuGet Manager - Recherche de T4MVC

NuGet va automatiquement installer les dépendances de T4MVC, dans notre cas T4MVCExtensions.

Installattino de T4MVC

L’installation de ce paquet se traduit par l’ajout de 3 fichiers à la racine du projet :

  • T4MVC.tt : le fichier template dont je parlais précédemment
  • T4MVC.tt.hooks.t4 : un fichier vous permettant d’ajouter votre propre code afin d’améliorer le code généré
  • T4MVC.tt.settings.xml : le fichier de configuration qui permet de notamment modifier les namespaces des fichiers générés

Fichiers T4MVC

La génération de code se fait en faisant un clic droit sur le fichier T4MVC.tt et en cliquant sur Run Custom Tool.

Lancement de la génération des fichiers

Une fois la génération effectuée, les fichiers générés se trouvent sous le fichier T4MVC.tt.

T4MVC : Fichiers générés

Je vous conseille également l’utilisation d’extension qui permet le lancement automatique de la transformation à la compilation de votre projet comme AutoT4MVC ou Chirpy. Sinon, vous devrez le lancer manuellement, ce qui s’avère lourd à force.

Activation de la compilation des vues

Par défaut, les vues ne sont pas compilés lors de la génération de la solution. Afin d’obtenir les erreurs dans vos vues à la compilation, il est nécessaire d’activer cette option. Pour cela il faut modifier le fichier .csproj (ou .vbproj) (via un éditeur de texte externe car non possible directement via VS …) et définir la propriété MvcBuildViews à true, comme dans l’exemple suivant :

<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    ...
    <MvcBuildViews>true</MvcBuildViews>
    ...
  </PropertyGroup>

La génération du projet sera donc un plus longue …

Utilisation

Comme précisé plus haut, T4MVC génère des classes contenant des méthodes / constantes permettant un code plus propre et plus maintenable. Nous allons voir 2 exemples avec les fichiers et les Actions mais il existe d’autres cas d’utilisation comme la redirection vers les vues, les routes … Je vous conseille la documentation du projet pour en savoir plus

Liens vers des fichiers

T4MVC génère pour les liens vers des fichiers un namespace Links (configurable dans le fichier de configuration) qui contient l’ensemble des fichiers de l’application (css, js, images, …). L’utilisation se fait via la syntaxe suivante Links.Folder.File. Ainsi on remplacera

<link rel="stylesheet" type="text/css" href="/Themes/default.css" />
<script src="/Scripts/jquery.min.js" type="text/javascript"</script>

par :

<link rel="stylesheet" type="text/css" href="@Links.Themes.default_css" />
<script src="@Links.Scripts.jquery_min_js" type="text/javascript"</script>

Comme vous pouvez le voir, les points et les – sont remplacés par des _, il faut donc faire attention au nom de vos fichiers au risque de vous retrouver avec 2 constantes avec le même nom, ce qui ne compilera pas !!!.

Actions

De la même façon, T4MVC génère un namespace MVC (configurable dans le fichier de configuration) contenant les méthodes des controllers. L’utilisation se fait via la syntaxe suivante MVC.Controller.Action. On remplacera donc la syntaxe

@Html.ActionLink('Home', 'Index')

par

@Html.ActionLink('Home', MVC.Home.Index())

Conclusion

T4MVC est un must have dans le développement d’applications ASP.NET MVC que je vous recommande d’utiliser et qui vous fera gagner un temps précieux lors de vos développements et la maintenance de votre application. T4MVC fait partie du projet MvcContrib qui permet de rajouter pas mal de possibilité dans le framework MVC comme des Helpers, des Filters, une librairie de tests, …

Outils CSS3 – HTML5 – JavaScript : Episode 4

HTML

Savez-vous qu’il est possible d’utiliser des caractères Unicode en tant qu’icône. Voici un tableau des différentes Icones web Unicode.

CSS

Les sélecteurs CSS

On retient souvent dans les nouveautés CSS3 ce qui concerne l’affichage (transformation, gradients, …) mais de nouveaux sélecteurs puissants ont également été introduits (:nth-child(expression), :contains(value), :checked, …). Voici un article qui explique les différents sélecteurs en CSS3 et une librairie selectivizr qui permet de supporter ces sélecteurs dans IE de la version 6 à 8.

Framework CSS

  • KNACSS : développé par Alsacréations
  • Ratchet : Un framework dédié au mobile. Idéal pour du prototypage.

Outils CSS

Divers

2 articles sur Smashing Magazine concernant des techniques JS/CSS qui peuvent s’avérer utiles (le premier et le deuxième). Voici 2 techniques/outils qui ont retenus mon attention :

JavaScript

Fuites Mémoires

Google a sorti Leak Finder un outil JavaScript open source pour trouver les fuites de mémoire dans vos applications

Framework MVC

TodoMVC : comparateur de framework JS MV*(M ou VM). Une application de gestion de tache (todo list) est implémentée avec différents framework (angular, ember, blackbone, knockout, …). A vous de choisir en fonction du type de la philosophie à adopter pour votre projet; Cela permet de comparer le code et d’avoir des bonnes pratiques pour débuter.

LINQ Pour JavaScript

Ceux qui travaillent dans le monde .NET doivent probablement connaitre LINQ qui est une technologie qui permet de requéter des sources de données hétérogène (base de donnée, objet, fichier XML, …). Il existe plusieurs librairies JavaScript qui permette d’effectuer des requêtes LINQ sur des objets JSON :

Librairies

Quelques librairies qui peuvent s’avérer pratique :

Jster : Catalogue de librairie JavaScript (plus de 750 à l’heure actuelle)

Mobilité

10 outils pour le Web mobile sur Alsacreations

Zen Coding devient Emmet

Quelques jours après la publication de mon article concernant Zen Coding, j’apprends que le projet change de nom et devient Emmet. Ce changement de nom est également synonyme de nouvelle version qui apporte quelques nouveautés (la liste complète des nouveautés) dont :