Durée : 10 minutes.

Il est courant dans les applications aujourd’hui de devoir uploader des fichiers. Mais diantre comment peut-on réaliser cela avec Angular2 sans utiliser de librairies encombrantes, et en oubliant la classe Http qui ne supporte pas l’upload de fichiers pour le moment ? La réponse est ici. 🙂

Un seul repère : XmlHttpRequest

XmlHttpRequest (XHR) est un objet JavaScript qui a été crée par Microsoft à l’origine, et qui permet de récupérer et d’envoyer facilement des données via HTTP. L’utilisation de XHR est très simple : après l’avoir instancier , il vous suffit d’ouvrir une URL et d’envoyer la requête.

Le code d’état HTTP de la réponse, ainsi que le document résultant sont disponibles dans l’instance de XHR après la requête.

Le vif du sujet : Un service pour uploader nos fichiers

Nous allons donc développer un service dans notre application qui gère l’upload de fichier via XHR. Afin de proposer une expérience asynchrone à l’utilisateur, nous service retournera une promesse, et nous prendrons en paramètre un objet File, de l’API File HTML5. Si vous ne savez pas ce qu’est une Promesse, j’ai rédigé un autre billet dessus, utiliser la barre de recherche du blog. : )

uploadFileXHR(file: File): Promise<any> { }

Afin d’uploader le fichier, nous utiliserons l’objet FormData. Cet objet permet de créer un ensemble de paires clef-valeur pour un envoie via XHR, et permet notamment l’envoie de fichier. Notre fichier sera donc envoyé via un objet FormData avec la clé file.

uploadFileXHR(file: File): Promise<any> {
  console.log('Upload the file ' + file.name);

  return new Promise((resolve, reject) => {
    let formData: FormData = new FormData();
    let xhr: XMLHttpRequest = new XMLHttpRequest();
    let url: string = "http://awesome-api.com/upload"; // à adapter

    formData.append("file", file); // ajout du fichier à la clé 'file'

    // traitement de la réponse de l'appel asynchrone
    xhr.onreadystatechange = () => {
      if (xhr.readyState === 4) {
        if (xhr.status === 200 || xhr.status === 201) {
            resolve(xhr);
        } else {
            reject(xhr);
        }
      }
    };

    xhr.open('POST', url, true); // configuration de l'objet XHR
    xhr.setRequestHeader("enctype", "multipart/form-data"); // envoie avec FormData
    xhr.send(formData); // envoie de la requête
  });
}

Le code est assez explicite avec les commentaires, si avez déjà une certaine connaissance de l’objet XHR et des Promesses.

Conclusion

Ce billet sert d’illustration à un concept bien connu en informatique, celui de toujours revenir aux bases quand on rencontre un problème haut niveau. Même si Angular ne propose pas de solution simple pour l’upload de fichier actuellement, il suffit de revenir à HTTP et XHR pour trouver une solution. Pensez-y la prochaine fois que vous bloquerez sur quelque chose ! : )

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion /  Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion /  Changer )

w

Connexion à %s