-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Full SPAddIn example #41
Comments
Hey @PSchicht, Thanks for the interest! What exactly does your Add-In request? Are you targeting the proxy to Add-In's SPWeb? I can take a look and provide some walkthrough, yet can't name any ETA. |
Hey @koltyakov , yes i have checked the post, for me it's not really clear on many points. I'm stuck with the installation. I followed installation instructions (https://github.com/koltyakov/sp-rest-proxy) and created the server.js file, run the npm run serve command and followed the instructions. However, when i try to open the http://localhost:8080/ url, i receive the following error message: Error: ENOENT: no such file or directory, open 'C:_Dev[...]\static\index.html' What am I doing wrong? Many thx for your help! |
Hey @koltyakov, I got it to work. I had to cover some new topics and stuff. I documented the steps, so I want to share them to help others :) Here are the steps that got me a fully functioning SPHostedAddIn with all the Angular 5 / Rest-Proxy good stuff: I used the "SharePoint Hosted Add-In with Angular 4" to get me started with Angular / SP-Hosted Add-In development a while back. (https://ramirezmery.wordpress.com/2017/08/16/sharepoint-hosted-add-in-with-Angular-4/). The basic creation and integration of the SharePoint project are based on this.
<rpt-root>Loading...</rpt-root>
<rpt-root>Loading...</rpt-root>
<script src="../app/src/inline.bundle.js"></script>
<script src="../app/src/polyfills.bundle.js"></script>
<script src="../app/src/styles.bundle.js"></script>
<script src="../app/src/vendor.bundle.js"></script>
<script src="../app/src/main.bundle.js"></script>
At this point, you should have a working Angular 5 Application. There are still some edges but for the most part it should be a good start. Now the HMR part: Follow the instructions to include HMR to your project: https://github.com/Angular/Angular-cli/wiki/stories-configure-hmr
export const environment = {
production: false,
hmr: true
};
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"hmr": "environments/environment.hmr.ts",
"prod": "environments/environment.prod.ts"
}
import { NgModuleRef, ApplicationRef } from '@Angular/core';
import { createNewHosts } from '@Angularclass/hmr';
export const hmrBootstrap = (module: any, bootstrap: () => Promise<NgModuleRef<any>>) => {
let ngModule: NgModuleRef<any>;
module.hot.accept();
bootstrap().then(mod => ngModule = mod);
module.hot.dispose(() => {
const appRef: ApplicationRef = ngModule.injector.get(ApplicationRef);
const elements = appRef.components.map(c => c.location.nativeElement);
const makeVisible = createNewHosts(elements);
ngModule.destroy();
makeVisible();
});
};
import { enableProdMode } from '@Angular/core';
import { platformBrowserDynamic } from '@Angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import { hmrBootstrap } from './hmr';
if (environment.production) {
enableProdMode();
}
const bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule);
if (environment.hmr) {
if (module[ 'hot' ]) {
hmrBootstrap(module, bootstrap);
} else {
console.error('HMR is not enabled for webpack-dev-server!');
console.log('Are you using the --hmr flag for ng serve?');
}
} else {
bootstrap();
}
Now we can include and configure SP-REST-PROY:
const RestProxy = require('sp-rest-proxy');
const settings = {
configPath: './config/private.json', // Location for SharePoint instance mapping and credentials
port: 8080, // Local server port
staticRoot: './app/src' // Root folder for static content in the app modules src folder
};
const restProxy = new RestProxy(settings);
restProxy.serve();
"scripts": {
"serve": "node ./server.js",
...
}
At this point the basic configuration is done. Now you can take the battle notes from here to refine your configuration. I added the proxy.conf.json file and changed my package.json to include at least the ""hmr": "ng serve --hmr --environment=hmr --verbose --proxy=proxy.conf.json"," script. To complete the application, I added a new service and created a method to query some SharePoint data
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { environment } from '../../environments/environment';
@Injectable()
export class SpRestService {
SPLocalUrl: string = 'http://localhost:4200';
SPHostUrl: string = '';
SPAppWebUrl: string = '';
constructor(private http: HttpClient) {
if (!environment.hmr) {
this.SPHostUrl = this.getQueryStringParameter('SPHostUrl');
this.SPAppWebUrl = this.getQueryStringParameter('SPAppWebUrl');
}
}
async executeTestQuery() {
let webServiceUrl: string = '';
let header: HttpHeaders;
if (environment.hmr) {
webServiceUrl = this.SPLocalUrl + "/_api/web/lists";
header = new HttpHeaders({ 'Content-Type': 'application/json;odata=verbose', 'Accept': 'application/json;odata=verbose' });
}
else {
webServiceUrl = this.SPAppWebUrl + "/_api/SP.AppContextSite(@target)/web/lists?@target='" + this.SPHostUrl + "'";
let digest: string = (<HTMLInputElement>document.getElementById('__REQUESTDIGEST')).value;
header = new HttpHeaders({ 'Content-Type': 'application/json;odata=verbose', 'Accept': 'application/json;odata=verbose', 'X-RequestDigest': digest });
}
let result = await this.executeRestQuery(webServiceUrl, header);
return result;
}
private executeRestQuery(webServiceUrl: string, header: HttpHeaders) {
return new Promise((resolve, reject) => {
let results: any = [];
this.http.get(webServiceUrl, { headers: header, withCredentials: true }).subscribe(
data => {
results = (data as any).d.results;
},
err => {
reject('Something went wrong!');
},
() => {
resolve(results);
}
);
});
}
private getQueryStringParameter(queryStringParameter): string {
var params =
document.URL.split("?")[1].split("&");
var strParams = "";
for (var i = 0; i < params.length; i = i + 1) {
var singleParam = params[i].split("=");
if (singleParam[0] == queryStringParameter)
return decodeURIComponent(singleParam[1].replace(/\+/g, ' '))
}
}
}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';
import { SpRestService } from './shared/sp-rest.service';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [
SpRestService
],
bootstrap: [AppComponent]
})
export class AppModule { }
<ul>
<li *ngFor="let item of queryResult">{{ item.Title }}</li>
</ul>
import { Component } from '@angular/core';
import { SpRestService } from './shared/sp-rest.service';
@Component({
selector: 'rpt-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'rpt';
queryResult: any = [];
constructor(private spRestService: SpRestService) {
this.executeTestQuery();
}
async executeTestQuery() {
this.queryResult = await this.spRestService.executeTestQuery();
}
}
The application is now complete. To start it locally:
To deploy it to SharePoint:
That's it so far. I'm not sure about the staticRoot: './app/src' part of the server.js file. Is it necessary to define the staticRoot? What do you think, is there something i missed? I will play around with the project a little more. So far i like it :) |
Cool stuff! It deserves to be a blog post! I can mention issue's tips which you've kindly created in project's readme. |
Hey,
I'm in a project where we host an angular 5 application in SharePoint 2013 using an SharePoint hosted Add-In. I have tried to use sp-rest-proxy with the add-in, but no luck. Can you please provide a step by step guide on how to use sp-rest-proxy with hosted Add-In?
Thanks!
The text was updated successfully, but these errors were encountered: