SharePoint Framework, Angular & Azure Functions SÉBASTIEN LEVERT VALO INTRANET, CANADA
Hi! I’m Seb! @sebastienlevert | http://sebastienlevert.com | Product Evangelist & Partner Manager at
AGENDA
SPFx & Angular
ANGULAR… BUT WHICH VERSION ? Works well with Angular 1.6 Works OK with Angular 2 Works awesome with Angular 5 (Angular 5!?)
IS THAT EVEN POSSIBLE ? Some are thinking it is mission impossible… But it is! And it’s much more simpler than you think. You have the full power of Angular within you own SPFx webparts Multiple web parts can exist in a page, including their own routing configuration
https://github.com/sebastienlevert/spfx-angular-boilerplate
DYNAMIC BOOTSTRAPPING protected get rootComponentType(): any { return AppComponent; } protected get appDeclarationTypes(): any { return [ DialogComponent, SitesComponent, SitesHomeComponent, SitesFormComponent, SitesViewComponent ]; }
DYNAMIC BOOTSTRAPPING private _bootStrapModule(): void { var self = this; platformBrowserDynamic().bootstrapModule(self._getModule()).then( ngModuleRef => { self._component = self._app['_rootComponents'][0]['_component’]; self.updateChanges(); self._zone.run(() => { console.log('Outside Done!'); }); }, err => { console.log(err); } ); }
DYNAMIC BOOTSTRAPPING const AppModule1 = Reflect.decorate([ NgModule({ imports: [BrowserModule, FormsModule, HttpModule, routes], declarations: declarations, bootstrap: [component], exports: [RouterModule], providers: providers }), Reflect.metadata('design:paramtypes', [ApplicationRef, NgZone]) ], AppModule);
ROUTING const routes: Routes = [ { path: '', component: SitesComponent, children: [ { path: '', component: SitesHomeComponent }, { path: 'sites', children: [ { path: 'new', component: SitesFormComponent }, { path: ':id', component: SitesViewComponent } ]}, ]} ]; import { appRoutes } from "./app/app.routes" protected get routes(): any { return appRoutes; }
GLOBAL CONFIGURATIONS import { ConfigurationService } from "./app/services/ConfigurationService"; ConfigurationService { provide: APP_INITIALIZER, useFactory: (configurationService: ConfigurationService) => () => configurationService.load({ functionUrl: this.properties.functionUrl, functionKey: this.properties.functionKey, description: this.properties.description, styles: styles }), deps: [ConfigurationService], multi: true }
MOCKING DATA if (Environment.type === EnvironmentType.Local) { return [ { provide: SitesService, useClass: MockSitesService }, ]; } else if (Environment.type == EnvironmentType.SharePoint || Environment.type == EnvironmentType.ClassicSharePoint) { return [ { provide: SitesService, useClass: SitesService }, ]; }
MOCKING DATA export class MockSitesService implements ISitesService { public createSite(siteInformation: ISiteCreationInformation): Observable<ISiteCreationResponse> { return Observable.of<ISiteCreationResponse>({ description: `${siteInformation.description} (Mocked)`, email: `${siteInformation.url}@mocked.onmicrosoft.com`, id: "00000000-0000-0000-0000-000000000000", title: `${siteInformation.title} (Mocked)`, url: `#${siteInformation.url}` }).delay(2000); } }
Azure Functions
WHY AZURE FUNCTIONS ? Cheap way to host any API in Azure You can use your favorite language Super cheap to run Perfect companion for any Single Page Application or any JavaScript component
OUR SCENARIO Using the PnP PowerShell Cmdlets Connecting to the Microsoft Graph and to an Azure AD Application Creating a Modern Team Site (in under 15 seconds) based on a set of parameters Boom!
Make it happen
THE COMPLETE SCENARIO Build a SharePoint Framework Web Part Use Angular as our main Framework Include 3 routes (Home, New Site and Site Information) Use Azure Function as my backend provisioning API Use the Office UI Fabric components
WHAT ABOUT THE OFFICE UI FABRIC ? Well… You have 2 choices : Build or Reuse My choice ? Reuse ! But Seb… It’s Angular, I can’t reuse what does not exist… Well… The React components exist, just reuse them !
DOWNSIDES Can’t use the CLI to build new components and slow to compile Can’t use AOT to reduce the bundle size Lots of “hacks” in code that make this approach… Clearly not SPCAF compliant!
LESSONS LEARNED Never use any class or ids from the DOM. Always use the ViewChild attribute. You can use html templates using the require() approach. Try to do that, React! When you have a strong AngularJS background, it feels just a little bit weird to move to Angular, but you will get used to it!
AND… SHOULD I USE IT IN PRODUCTION? As of today, this approach is the only approach that works. Use it to experiment, to learn the SharePoint Framework and Angular altogether. Will require a lot of maintenance with new versions of SPFx… In short, I would not go all in right now… But…
BUT… SharePoint & Angular Elements | Thursday @ 10h20
Next Steps
RESOURCES https://github.com/SharePoint/sp-dev-fx- webparts/tree/master/samples/angular2-prototype https://dev.office.com/sharepoint/docs/spfx/sharepoint- framework-overview http://dev.office.com/fabric#/components https://www.youtube.com/watch?v=Vkzr2TxHFLg&t=6s
SAMPLES https://github.com/sebastienlevert/spfx-angular- boilerplate https://github.com/sebastienlevert/spfx-angular-samples
SHARING IS CARING Use hashtags to share your experience #Office365Dev #MicrosoftGraph #AzureFunctions #SPFx Log issues & questions to the GitHub Repositories
Thank you! @sebastienlevert | http://sebastienlevert.com | Product Evangelist & Partner Manager at

European SharePoint Conference 2017 - SharePoint Framework, Angular & Azure Functions

  • 2.
    SharePoint Framework, Angular& Azure Functions SÉBASTIEN LEVERT VALO INTRANET, CANADA
  • 3.
    Hi! I’m Seb! @sebastienlevert| http://sebastienlevert.com | Product Evangelist & Partner Manager at
  • 4.
  • 6.
  • 7.
    ANGULAR… BUT WHICHVERSION ? Works well with Angular 1.6 Works OK with Angular 2 Works awesome with Angular 5 (Angular 5!?)
  • 8.
    IS THAT EVENPOSSIBLE ? Some are thinking it is mission impossible… But it is! And it’s much more simpler than you think. You have the full power of Angular within you own SPFx webparts Multiple web parts can exist in a page, including their own routing configuration
  • 9.
  • 11.
    DYNAMIC BOOTSTRAPPING protected getrootComponentType(): any { return AppComponent; } protected get appDeclarationTypes(): any { return [ DialogComponent, SitesComponent, SitesHomeComponent, SitesFormComponent, SitesViewComponent ]; }
  • 12.
    DYNAMIC BOOTSTRAPPING private _bootStrapModule():void { var self = this; platformBrowserDynamic().bootstrapModule(self._getModule()).then( ngModuleRef => { self._component = self._app['_rootComponents'][0]['_component’]; self.updateChanges(); self._zone.run(() => { console.log('Outside Done!'); }); }, err => { console.log(err); } ); }
  • 13.
    DYNAMIC BOOTSTRAPPING const AppModule1= Reflect.decorate([ NgModule({ imports: [BrowserModule, FormsModule, HttpModule, routes], declarations: declarations, bootstrap: [component], exports: [RouterModule], providers: providers }), Reflect.metadata('design:paramtypes', [ApplicationRef, NgZone]) ], AppModule);
  • 14.
    ROUTING const routes: Routes= [ { path: '', component: SitesComponent, children: [ { path: '', component: SitesHomeComponent }, { path: 'sites', children: [ { path: 'new', component: SitesFormComponent }, { path: ':id', component: SitesViewComponent } ]}, ]} ]; import { appRoutes } from "./app/app.routes" protected get routes(): any { return appRoutes; }
  • 15.
    GLOBAL CONFIGURATIONS import {ConfigurationService } from "./app/services/ConfigurationService"; ConfigurationService { provide: APP_INITIALIZER, useFactory: (configurationService: ConfigurationService) => () => configurationService.load({ functionUrl: this.properties.functionUrl, functionKey: this.properties.functionKey, description: this.properties.description, styles: styles }), deps: [ConfigurationService], multi: true }
  • 16.
    MOCKING DATA if (Environment.type=== EnvironmentType.Local) { return [ { provide: SitesService, useClass: MockSitesService }, ]; } else if (Environment.type == EnvironmentType.SharePoint || Environment.type == EnvironmentType.ClassicSharePoint) { return [ { provide: SitesService, useClass: SitesService }, ]; }
  • 17.
    MOCKING DATA export classMockSitesService implements ISitesService { public createSite(siteInformation: ISiteCreationInformation): Observable<ISiteCreationResponse> { return Observable.of<ISiteCreationResponse>({ description: `${siteInformation.description} (Mocked)`, email: `${siteInformation.url}@mocked.onmicrosoft.com`, id: "00000000-0000-0000-0000-000000000000", title: `${siteInformation.title} (Mocked)`, url: `#${siteInformation.url}` }).delay(2000); } }
  • 18.
  • 19.
    WHY AZURE FUNCTIONS? Cheap way to host any API in Azure You can use your favorite language Super cheap to run Perfect companion for any Single Page Application or any JavaScript component
  • 20.
    OUR SCENARIO Using thePnP PowerShell Cmdlets Connecting to the Microsoft Graph and to an Azure AD Application Creating a Modern Team Site (in under 15 seconds) based on a set of parameters Boom!
  • 21.
  • 22.
    THE COMPLETE SCENARIO Builda SharePoint Framework Web Part Use Angular as our main Framework Include 3 routes (Home, New Site and Site Information) Use Azure Function as my backend provisioning API Use the Office UI Fabric components
  • 23.
    WHAT ABOUT THEOFFICE UI FABRIC ? Well… You have 2 choices : Build or Reuse My choice ? Reuse ! But Seb… It’s Angular, I can’t reuse what does not exist… Well… The React components exist, just reuse them !
  • 24.
    DOWNSIDES Can’t use theCLI to build new components and slow to compile Can’t use AOT to reduce the bundle size Lots of “hacks” in code that make this approach… Clearly not SPCAF compliant!
  • 25.
    LESSONS LEARNED Never useany class or ids from the DOM. Always use the ViewChild attribute. You can use html templates using the require() approach. Try to do that, React! When you have a strong AngularJS background, it feels just a little bit weird to move to Angular, but you will get used to it!
  • 26.
    AND… SHOULD IUSE IT IN PRODUCTION? As of today, this approach is the only approach that works. Use it to experiment, to learn the SharePoint Framework and Angular altogether. Will require a lot of maintenance with new versions of SPFx… In short, I would not go all in right now… But…
  • 27.
    BUT… SharePoint & AngularElements | Thursday @ 10h20
  • 28.
  • 29.
  • 30.
  • 31.
    SHARING IS CARING Usehashtags to share your experience #Office365Dev #MicrosoftGraph #AzureFunctions #SPFx Log issues & questions to the GitHub Repositories
  • 32.
    Thank you! @sebastienlevert |http://sebastienlevert.com | Product Evangelist & Partner Manager at