Introduction
In this post, I will show you how to use AngularJS in SPFx. I have divided the process into steps for better understanding.
Steps
- Create an SPFx Project without JavaScript Web Framework
- Add Dev Dependencies
- Remove some Dependencies
- Run “npm install”
- Modify “config.json”
- Create a folder called “app” under “/src/webparts/ angularjsWebpart/” and create the following files in the “app” folder,
- Greetings.component.html
- Greeting.module.css
- Greetings.component.ts
- Greetings.service.ts (If required)
- app.module.ts
- Modify “<<your_webpart>>webpart.ts” file & add some code.
- Finally, run your solution
Create an SPFx Project without JavaScript Web Framework
Remember that you have to create a project with No javascript web framework option.
Create a new project directory in your favorite location.
md angularjs-webpart
Go to the project directory.
cd angularjs-webpart
Create a new angularjs web part by running the Yeoman SharePoint Generator.
yo @microsoft/sharepoint
When prompted:
- Accept the default angularjs-webpart as your solution name, and then select Enter.
- Select SharePoint Online only (latest), and select Enter.
- Select Use the current folder for where to place the files.
- Select N to not allow the solution to be deployed to all sites immediately.
- Select N on the question if solution contains unique permissions.
- Select WebPart as the client-side component type to be created.
The next set of prompts ask for specific information about your web part:
- Accept the default angularjs as your web part name, and then select Enter.
- Accept the default angularjs description as your web part description, and then select Enter.
- Accept the default No javascript web framework as the framework you would like to use, and then select Enter.
At this point, Yeoman installs the required dependencies and scaffolds the solution files along with the angularjs web part. This might take a few minutes.
When the scaffold is complete, you should see the following message indicating a successful scaffold.
Add Dev Dependencies
After creating the project, open this in Visual Studio Code. Now open “package.json” and add the following line of code in the “devDependencies” section:
- "@types/angular": "^1.6.57",
- "@types/jquery": "^3.3.31",
- "@types/es6-promise": "0.0.33",
- "@types/webpack-env": "1.13.1",
- "sp-pnp-js": "^3.0.10"
Here, we are installing developer dependencies for AngularJS, Jquery & sp-pnp-js.
Remove Dependencies
Remove the following code from the “dependencies” section,
- "@types/es6-promise": "0.0.33",
- "@types/webpack-env": "1.13.1"
Run “npm install”
Now we have to run the npm install command to install dependencies in our project.
Modify “config.json”
Navigate to the “config” folder and open “config.json” & modify the “externals” section with the following values:
- "externals": {
- "jquery": "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js",
- "angular": {
- "path": "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js",
- "globalName": "angular"
- },
- "es-promise": "https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.min.js",
- "fetch": "https://cdnjs.cloudflare.com/ajax/libs/fetch/3.0.0/fetch.js",
- "sp-pnp-js": "https://cdnjs.cloudflare.com/ajax/libs/sp-pnp-js/3.0.10/pnp.min.js"
- },
Create a folder called “app” under “/src/webparts/angularjsWebpart /” and create the following files in the “app” folder,
Greetings.component.html
- <div class="demo" ng-cloak>
- <div class="container">
- <div class="row">
- <div class="col-lg-12 col-md-12 col-sm-12">
- <div class="email-signature">
- <div class="signature-img">
- <img ng-src="{{$ctrl.userImageUrl}}" alt="">
- </div>
- <div class="signature-details">
- <h3 class="title">{{$ctrl.userName}}</h3>
- <span class="post">{{$ctrl.userJobTitle}}</span>
- </div>
- <ul class="signature-content">
- <li>
- <span class="fas fa-map-marker-alt"></span> {{$ctrl.greetingMessage}}
- </li>
- <li>
- <span class="fas fa-envelope"></span> {{$ctrl.webSiteTitle}}
- </li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- </div>
Greeting.module.css
- :root {
- --color_0: #000;
- --color_1: #fff;
- --name: #abb7c5;
- --shadow: rgba(0, 0, 0, 0.5);
- --main_bg: linear-gradient(to right, #181623 13%, #3c3b43 21%);
- --before_bg: linear-gradient(to bottom, #f9da41, #fa771c);
- --after_bg: linear-gradient(to bottom, #a2eee1, #1b819a);
- --main_bg_res: linear-gradient(to top, #181623 13%, #3c3b43 21%);
- --before_bg_res: linear-gradient(to right, #f9da41, #fa771c);
- --after_bg_res: linear-gradient(to right, #a2eee1, #1b819a);
- }
-
- .email-signature {
- background: var(--main_bg);
- font-family: "Roboto", sans-serif;
- padding: 20px 185px 20px 10px;
- box-shadow: 0 0 10px var(--shadow);
- position: relative;
- text-align: center;
- }
-
- .email-signature:before,
- .email-signature:after {
- content: "";
- background: var(--before_bg);
- height: 100%;
- width: 100px;
- position: absolute;
- right: 0;
- top: 0;
- }
-
- .email-signature:after {
- background: var(--after_bg);
- width: 20px;
- right: 110px;
- }
-
- .email-signature .signature-img {
- height: 140px;
- width: 140px;
- border: 7px solid var(--color_1);
- border-radius: 25px;
- overflow: hidden;
- transform: translateY(-50%);
- position: absolute;
- right: 35px;
- top: 50%;
- z-index: 1;
- }
-
- .email-signature .signature-img img {
- width: 100%;
- height: auto;
- }
-
- .email-signature .signature-details {
- color: var(--name);
- font-size: 15px;
- margin-bottom: 20px;
- text-align: center;
- }
-
- .email-signature .title {
- font-size: 22px;
- font-weight: 600;
- text-transform: uppercase;
- letter-spacing: 1px;
- margin: 0;
- display: block;
- }
-
- .email-signature .title span {
- font-weight: 400;
- }
-
- .email-signature .signature-content {
- color: var(--color_1);
- font-size: 14px;
- line-height: 28px;
- padding: 0 0 0 20px;
- margin: 0;
- list-style: none;
- }
-
- .email-signature .signature-content li span {
- margin-right: 6px;
- }
-
- .email-signature .icon {
- background-color: var(--color_1);
- height: 100%;
- padding: 65px 30px;
- margin: 0;
- list-style: none;
- position: absolute;
- left: 0;
- top: 0;
- }
-
- .email-signature .icon li a {
- color: var(--color_1);
- background-color: var(--name);
- font-size: 16px;
- text-align: center;
- line-height: 25px;
- height: 25px;
- width: 25px;
- margin-bottom: 10px;
- display: block;
- transition: all 0.3s ease 0s;
- }
-
- .email-signature .icon li a:hover {
- color: var(--name);
- background-color: var(--color_0);
- text-decoration: none;
- box-shadow: 0 0 10px var(--shadow);
- }
-
- @media screen and (max-width: 767px) {
- .email-signature {
- background: var(--main_bg_res);
- text-align: center;
- padding: 175px 20px 70px 20px;
- }
-
- .email-signature .signature-img {
- transform: translateY(0) translateX(-50%);
- top: 20px;
- left: 50%;
- }
-
- .email-signature:before,
- .email-signature:after {
- background: var(--before_bg_res);
- width: 100%;
- height: 70px;
- transform: translateY(0);
- top: 0;
- left: 0;
- }
-
- .email-signature:after {
- background: var(--after_bg_res);
- height: 20px;
- top: 85px;
- }
-
- .email-signature .signature-details {
- margin: 0 0 5px 0;
- }
-
- .email-signature .signature-content {
- padding: 0;
- }
-
- .email-signature .icon {
- width: 100%;
- height: auto;
- padding: 15px 0;
- top: auto;
- bottom: 0;
- }
-
- .email-signature .icon li {
- display: inline-block;
- }
-
- .email-signature .icon li a {
- margin: 0 5px;
- }
- }
Greetings.component.ts
- import {
- GreetingService
- } from "./Greetings.service";
- export class GreetingController {
- public userName: string = "";
- public userJobTitle: string = "";
- public webSiteTitle: string = "";
- public welComeMessage: string = "";
- public userImageUrl: string = "";
- public greetingMessage: string = "";
- public prefixWelcomeMessage: string = "Welcome to ";
- public static $inject: string[] = ["GreetingService", "$scope"];
- constructor(
-
- private GreetingService: GreetingService, private $scope: ng.IScope) {
- this.$scope.$on("configurationChangedGreetingWebPart",
- (event: ng.IAngularEvent, data: any) => {
- this.webSiteTitle = data.webTitle;
- this.userName = data.userDisplayName;
- this.getValues();
- console.log(this.userImageUrl);
-
- });
- this.getValues();
- }
- public getValues = () => {
- if (new Date().getHours() > 0 && new Date().getHours() < 12) this.greetingMessage = "Good Morning ";
- else if (new Date().getHours() >= 12 && new Date().getHours() <= 5) this.greetingMessage = "Good Afternoon ";
- else if (new Date().getHours() > 5) this.greetingMessage = "Good Evening ";
- if (this.userName.length == 0) this.userName = "Gaurav Goyal";
- if (this.userJobTitle.length == 0) this.userJobTitle = "";
- if (this.webSiteTitle.length == 0) this.webSiteTitle = this.prefixWelcomeMessage + "Demo of SPFx Web Part";
- if (this.welComeMessage.length == 0) this.welComeMessage = this.greetingMessage + this.userName;
-
-
- this.getCurrentUserInformation();
- }
- public getCurrentUserInformation = () => {
- this.GreetingService.getCurrentUserInformation().then(ig => {
- this.webSiteTitle = this.prefixWelcomeMessage + this.webSiteTitle;
- this.userImageUrl = ig.userImageUrl;
-
- this.userJobTitle = ig.userJobTitle;
- this.$scope.$apply();
- });
- }
- }
- export let GreetingComponent = {
- selector: "greetingComponent",
- template: require("./Greetings.component.html").toString(),
- bindings: {},
- controller: GreetingController,
- styles: require("./Greeting.module.css").toString()
- };
Greetings.service.ts (If required)
- import {
- IGreeting
- } from "./IGreeting";
-
- import * as $pnp from "sp-pnp-js";
- export class GreetingService {
- constructor() {}
- public getCurrentUserInformation = (): Promise < IGreeting > => {
- let promise = new Promise < IGreeting > ((resolve, reject) => {
- let ig: IGreeting = {
- userImageUrl: "",
- userJobTitle: "",
- userName: "",
- webSiteTitle: ""
- };
- $pnp.sp.profiles.myProperties.get().then(data => {
- data.UserProfileProperties.forEach(property => {
- if (property.Key == "Title") {
- ig.userJobTitle = property.Value;
- }
- if (property.Key == "PictureURL") {
- if (property.Value !== '') {
- ig.userImageUrl = property.Value;
- } else {
- ig.userImageUrl = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png";
- }
- ig.userImageUrl = ig.userImageUrl.replace("MThumb", "LThumb");
- }
- });
- resolve(ig);
- }, error => {
- reject(error);
- });
- });
- return promise;
- }
- }
app.module.ts
- import * as angular from 'angular';
- import {GreetingComponent, GreetingController} from './Greetings.component';
- import { GreetingService } from './Greetings.service';
- const greetingApp: angular.IModule = angular.module('greeting-webpart-app', []);
- greetingApp
- .service("GreetingService", GreetingService);
- greetingApp
- .controller('GreetingController', GreetingController);
- greetingApp
- .component(GreetingComponent.selector, GreetingComponent);
Modify “<<your_webpart>>webpart.ts” file & add some code.
At the top of the file, add 2 highlighted lines.
- import { Version } from '@microsoft/sp-core-library';
- import {
- IPropertyPaneConfiguration,
- PropertyPaneTextField
- } from '@microsoft/sp-property-pane';
- import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
- import { escape } from '@microsoft/sp-lodash-subset';
- import styles from './GreetingsWebpartWebPart.module.scss';
- import * as strings from 'GreetingsWebpartWebPartStrings';
- export interface IGreetingsWebpartWebPartProps {
- description: string;
- }
- import * as angular from "angular";
- import "./app/app.module";
Replace the render function:
- public render(): void {
- if (this.renderedOnce === false) {
- this.domElement.innerHTML = `<greeting-component></greeting-component>`;
- this.$injector = angular.bootstrap(this.domElement, ["greeting-webpart-app"]);
- }
- let obj1 = {
-
- currentUserId: this.context.pageContext.legacyPageContext['userId'],
- webAbsoluteUrl: this.context.pageContext.legacyPageContext['webAbsoluteUrl'],
- webTitle: this.context.pageContext.legacyPageContext['webTitle'],
- userDisplayName: this.context.pageContext.legacyPageContext['userDisplayName'],
- tempData: this.properties.description
- };
- this.$injector.get("$rootScope").$broadcast("configurationChangedGreetingWebPart", obj1);
- }
Finally, run your solution.
gulp serve –nobrowser
Run your Sharepoint workbench.
https://<<TenantName>>.sharepoint.com/_layouts/15/workbench.aspx
Add webpart & see the result.
My sample code is part of the PnP community - SPFx Dev webpart sample.
Click here to download the code.
Output