Angular & Microsoft Graph [Part 5] : Onedrive

On a vu dans les précédents articles comment jouer avec Microsoft Graph concernant les calendriers et les évènements. Regardons maintenant comment jouer avec Onedrive.

Dans l'application, on gère un ensemble de clients. Il faut pouvoir sauvegarder l'ensemble de ces clients dans Office365. Une solution simple (mais non viable si l'on a beaucoup de données), c'est de stocker cela dans un fichier dans OneDrive.

C'est le cas de notre application (si, si, je vous assure). Donc nous allons sauvegarder et récupérer ces données depuis un fichier OneDrive de l'utilisateur stocké dans le dossier myTjm/clients.json.

Pour récupérer le contenu d'un fichier, il y a 2 étapes :

  • la première consiste à récupérer l'URL du contenu du fichier,
  • récupérer son contenu à partir de l'URL précédente.

L'URL du contenu d'un fichier est accessible dans les données d'un fichier, et pour récupérer les données d'un fichier, on a une méthode GET vers l'URL constituée ainsi :

me/drive/root:/{chemin du fichier}:/

Comme ce qui nous intéresse ce n'est que l'URL du contenu du fichier, on va faire un select :

me/drive/root:/{chemin du fichier}:/?select=@microsoft.graph.downloadUrl

Du coup, pour récupérer le contenu d'un fichier, j'ai crée un service, FileService avec la méthode suivante :

@Injectable({
  providedIn: 'root'
})
export class FilesService extends GraphBaseService {

  constructor(httpClient: HttpClient) { super(httpClient); }

  loadFile(fileName: string) {
    const url = GraphUrl + '/me/drive/root:/myTjm/' + fileName + ':/?select=@microsoft.graph.downloadUrl';
    return this.httpClient.get(url)
      .pipe(
        mergeMap(result => {

          const downloadUrl = result['@microsoft.graph.downloadUrl'];
          return this.httpClient.get(downloadUrl);
        }));
  }

  //...
}

On appele une première fois pour obtenir l'URL et une seconde fois pour le contenu (remarquez l'utilisation de MergeMap pour retourner l'Observable de rxjs).

Donc dans mon service ClientsService, il me suffit d'appeler cette méthode avec comme nom de fichier clients.json :

public load(): Observable<IClient[]> {
    return this.filesService.loadFile(ClientsFileName).pipe(
      mergeMap(content => {
        const clients = <IClient[]>content;
        this.saveLocal(clients);
        return of(clients);
      }),
      catchError(err => {
        const localDatas: IClient[] = <IClient[]>JSON.parse(localStorage.getItem(ClientsKey));
        return of(localDatas);
      })
    );
  }

Remarquez que je sauvegarde le contenu télécharger dans le localstorage (via la méthode saveLocal).

C'est le même principe pour sauvegarder un fichier sur OneDrive. Cette fois, on va utiliser un PUT sur l'URL :

me/drive/root:/{chemin du fichier}:/content

D'ou la méthode dans le FileService pour sauvegarder un fichier filename avec un contenu content :

saveFile(fileName: string, content: string) {
    const url = GraphUrl + '/me/drive/root:/myTjm/' + fileName + ':/content';
    return this.httpClient.put(url, content);
  }

Et dans le service ClientsService, le contenu est le contenu sérialisé en JSON de nos clients :

private save(clients: IClient[]): Observable<any> {
    this.saveLocal(clients);
    return this.filesService.saveFile(ClientsFileName, JSON.stringify(clients));
  }

Lire et enregistrer le contenu d'un fichier sur OneDrive est donc un jeu d'enfant.

blog comments powered by Disqus