Skip to content

Commit 1c427a6

Browse files
committed
showcase req res, globals, and passing server data to client
1 parent 90d3c86 commit 1c427a6

File tree

6 files changed

+120
-19
lines changed

6 files changed

+120
-19
lines changed

Client/app/app.component.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, ViewEncapsulation } from '@angular/core';
1+
import { Component, ViewEncapsulation, Inject } from '@angular/core';
22
import { isBrowser, isNode } from 'angular2-universal';
33

44
@Component({
@@ -14,16 +14,9 @@ import { isBrowser, isNode } from 'angular2-universal';
1414
})
1515
export class AppComponent {
1616

17-
constructor() {
18-
19-
if (isBrowser) {
20-
// With use of isBrowser or isNode you could do conditional things
21-
// in the different environments!
22-
23-
// IE: Let's say you wanted to touch the `window` or `document`
24-
// This would break on the server-side, but not in the browser!
25-
}
26-
17+
constructor(@Inject('req') req: any, @Inject('res') res: any) {
18+
console.log('req', req);
19+
console.log('res', res);
2720
}
2821

2922
}

Client/app/platform-modules/app.browser.module.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { RouterModule } from '@angular/router';
33
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
44
import { Store, StoreModule } from '@ngrx/store';
55
// for AoT we need to manually split universal packages (/browser & /node)
6-
import { UniversalModule, isBrowser, isNode } from 'angular2-universal/browser';
6+
import { UniversalModule, isBrowser, isNode, AUTO_PREBOOT } from 'angular2-universal/browser';
77

88
import { AppCommonModule } from './common.module';
99
import { AppComponent } from 'app';
@@ -12,6 +12,13 @@ import { CacheService } from 'app-shared';
1212

1313
export const UNIVERSAL_KEY = 'UNIVERSAL_CACHE';
1414

15+
export function getRequest() {
16+
return {};
17+
}
18+
export function getResponse() {
19+
return {};
20+
}
21+
1522
@NgModule({
1623
bootstrap: [ AppComponent ],
1724
imports: [
@@ -26,10 +33,15 @@ export const UNIVERSAL_KEY = 'UNIVERSAL_CACHE';
2633
StoreDevtoolsModule.instrumentOnlyWithExtension()
2734
],
2835
providers: [
29-
// Can be used inside Components within the app to declaritively run code
30-
// depending on the platform it's in
31-
{ provide: 'isBrowser', useValue: isBrowser },
32-
{ provide: 'isNode', useValue: isNode }
36+
// Angular -Universal- providers below ::
37+
{ provide: 'isBrowser', useValue: isBrowser },
38+
{ provide: 'isNode', useValue: isNode },
39+
{ provide: 'req', useFactory: getRequest },
40+
{ provide: 'res', useFactory: getResponse }
41+
// Universal concept. Uncomment this if you want to Turn OFF auto preboot complete
42+
// { provide: AUTO_PREBOOT, useValue: false }
43+
44+
// Other providers you want to add that you don't want shared in "Common" but are browser only
3345
]
3446
})
3547
export class AppBrowserModule {

Client/app/platform-modules/app.server.module.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ import { AppComponent } from 'app';
1111
// Universal : XHR Cache
1212
import { CacheService } from 'app-shared';
1313

14+
export function getRequest() {
15+
return Zone.current.get('req') || {};
16+
}
17+
export function getResponse() {
18+
return Zone.current.get('res') || {};
19+
}
20+
1421
@NgModule({
1522
bootstrap: [ AppComponent ],
1623
imports: [
@@ -25,7 +32,11 @@ import { CacheService } from 'app-shared';
2532
// Can be used inside Components within the app to declaritively run code
2633
// depending on the platform it's in
2734
{ provide: 'isBrowser', useValue: isBrowser },
28-
{ provide: 'isNode', useValue: isNode }
35+
{ provide: 'isNode', useValue: isNode },
36+
{ provide: 'req', useFactory: getRequest },
37+
{ provide: 'res', useFactory: getResponse }
38+
39+
// Other providers you want to add that you don't want shared in "Common" but are browser only
2940
]
3041
})
3142
export class AppServerModule {

Client/bootstrap-server.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ enableProdMode();
1111

1212
declare var Zone: any;
1313

14-
export default function (params: any): Promise<{ html: string, globals?: any }> {
14+
export default function (params: IParams): Promise<{ html: string, globals?: any }> {
1515

1616
const doc = `
1717
<!DOCTYPE html>\n
@@ -56,10 +56,18 @@ export default function (params: any): Promise<{ html: string, globals?: any }>
5656
})
5757
).then(html => {
5858

59+
// Something went wrong, return the original blank document at least
5960
if (typeof html !== 'string') {
6061
return { html: doc };
6162
}
62-
return { html };
63+
64+
/* Successfully serialized Application
65+
* You can pass "Globals" here if you want to pass some data to every request
66+
* (also you could pass in params.data if you want to pass data from the server that came through the Views/Index.cshtml page
67+
* inside of the asp-prerender-data="" attribute
68+
* globals: params.data
69+
*/
70+
return { html /*, globals: someObject */ };
6371

6472
}).catch(err => {
6573

@@ -69,3 +77,10 @@ export default function (params: any): Promise<{ html: string, globals?: any }>
6977
});
7078

7179
}
80+
81+
export interface IParams {
82+
origin: string;
83+
url: string;
84+
absoluteUrl: string;
85+
data: {}; // custom user data sent from server (through asp-prerender-data="" attribute on index.cshtml)
86+
}

Client/typings.d.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Custom Type Definitions
3+
* When including 3rd party modules you also need to include the type definition for the module
4+
* if they don't provide one within the module. You can try to install it with typings
5+
typings install node --save
6+
* If you can't find the type definition in the registry we can make an ambient definition in
7+
* this file for now. For example
8+
declare module "my-module" {
9+
export function doesSomething(value: string): string;
10+
}
11+
*
12+
* If you're prototying and you will fix the types later you can also declare it as type any
13+
*
14+
declare var assert: any;
15+
*
16+
* If you're importing a module that uses Node.js modules which are CommonJS you need to import as
17+
*
18+
import * as _ from 'lodash'
19+
* You can include your type definitions in this file until you create one for the typings registry
20+
* see https://github.com/typings/registry
21+
*
22+
*/
23+
24+
// declare module '*'; // default type definitions for any for modules that are not found.
25+
// caveat: if this is enabled and you do not have the proper module there may not be an error.
26+
// suggestion: follow the pattern below with modern-lru which provides an alternative way to create an 'any' module.
27+
28+
// for legacy tslint etc to understand
29+
declare module 'modern-lru' {
30+
let x: any;
31+
export = x;
32+
}
33+
34+
// Extra variables that live on Global that will be replaced by webpack DefinePlugin
35+
declare var ENV: string;
36+
declare var HMR: boolean;
37+
declare var Zone: {current: any};
38+
interface GlobalEnvironment {
39+
ENV;
40+
HMR;
41+
}
42+
43+
interface WebpackModule {
44+
hot: {
45+
data?: any,
46+
idle: any,
47+
accept(dependencies?: string | string[], callback?: (updatedDependencies?: any) => void): void;
48+
decline(dependencies?: string | string[]): void;
49+
dispose(callback?: (data?: any) => void): void;
50+
addDisposeHandler(callback?: (data?: any) => void): void;
51+
removeDisposeHandler(callback?: (data?: any) => void): void;
52+
check(autoApply?: any, callback?: (err?: Error, outdatedModules?: any[]) => void): void;
53+
apply(options?: any, callback?: (err?: Error, outdatedModules?: any[]) => void): void;
54+
status(callback?: (status?: string) => void): void | string;
55+
removeStatusHandler(callback?: (status?: string) => void): void;
56+
};
57+
}
58+
59+
interface WebpackRequire {
60+
context(file: string, flag?: boolean, exp?: RegExp): any;
61+
}
62+
63+
// Extend typings
64+
interface NodeRequire extends WebpackRequire {}
65+
interface NodeModule extends WebpackModule {}
66+
interface Global extends GlobalEnvironment {}

webpack.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ module.exports = setTypeScriptAlias(require('./tsconfig.json'), {
135135

136136
].concat(isDevBuild ? [] : [
137137
// Plugins that apply in production builds only
138+
139+
// problem with platformUniversalDynamic on the server/client
140+
new webpack.IgnorePlugin(/@angular(\\|\/)compiler/),
141+
138142
//new webpack.optimize.OccurrenceOrderPlugin(), <-- not needed in webpack2 anymore
139143
new webpack.optimize.UglifyJsPlugin()
140144
]),

0 commit comments

Comments
 (0)