Skip to content
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

Merge pull request #16 from l request #1 #5

Open
wants to merge 54 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
d45451b
docs(contributing.md): add docs for "build" commit type
IgorMinar Dec 9, 2015
ad1cd79
docs(contributing.md): improve submit issue instructions
IgorMinar Dec 15, 2015
c4a4036
Merge pull request #16 from usernamealreadyis/master
usernamealreadyis Jan 2, 2016
9d28147
fix(benchpress): fix flake
hankduan Dec 29, 2015
a038bb9
fix(router): preserve specificity for redirects
btford Dec 15, 2015
b44d36c
fix(forms): fix SelectControlValueAccessor not to call onChange twice
vsavkin Dec 16, 2015
4291758
build(sauce/bs): make some browsers required in CI
marclaval Dec 10, 2015
0b6e75a
chore(ci): cleanup artifact upload
alexeagle Jan 3, 2016
a08f50b
chore(build): allow to run examples and benchmarks without bundles
tbosch Dec 30, 2015
7ae23ad
feat(core): speed up view creation via code gen for view factories.
tbosch Dec 2, 2015
89f32f8
perf(dart/transform): Avoid unnecessary reads for files with no view
Dec 30, 2015
6343f71
chore(release): 2.0.0-beta.1 - catamorphic-involution
rkirov Jan 8, 2016
041c599
docs(changelog): update change log to beta.1
rkirov Jan 8, 2016
c56679e
Update change from Apache to MIT license
naomiblack Jan 8, 2016
b3c7df1
docs(cheatsheet): fix bootstrap ts namespace
filipesilva Dec 28, 2015
95248f4
build(npm): update to ts2dart@0.7.19
vikerman Jan 4, 2016
69ae363
feat(testability): Expose function frameworkStabilizers
hankduan Jan 5, 2016
c8e909f
docs(cheatsheet): fix pipe name in an example
bjwyse Jan 11, 2016
8c37b7e
fix(directive): throw if output the same event more than once
erictsangx Nov 4, 2015
933a911
fix(ChangeDetection): chain expressions evaluate to the last expressi…
vicb Dec 15, 2015
b0cebdb
feat(test): allow tests to specify the platform and application provi…
juliemr Dec 16, 2015
ac85cbb
fix(web_workers): support @AngularEntrypoint in web workers
yjbanov Dec 19, 2015
6b73d09
chore(build): make experimental Dart build useful
yjbanov Jan 12, 2016
c1c54ed
refactor(dart/transform): Avoid using package:code_transformers
Dec 16, 2015
eda6a5d
refactor(WebWorker): Rename WORKER_RENDER_APP to WORKER_RENDER_APPLIC…
jteplitz Dec 31, 2015
4d0c2ed
test(dart/transform): Update dependencies & fix Dart tests
Dec 16, 2015
97ebc81
requirements.txt
usernamealreadyis Jan 14, 2016
a6e116f
Merge branch 'master' into patch-9
usernamealreadyis Jan 14, 2016
eda4c3e
fix(template_compiler): Fix erroneous cycle detection
tbosch Jan 14, 2016
8bd697b
docs(DEVELOPER): fix saucelabs gulp task name
juliemr Jan 12, 2016
92dc3b9
doc(*): change package.json license field to MIT
urish Jan 12, 2016
ae05ec6
Update overview.md
BeastCode Jan 14, 2016
ca7ba12
chore(travis): update name of sync branch to be ignored
jeffbcross Jan 15, 2016
bd015f1
build(dartanalyzer): Ignore TODOs during build
Jan 11, 2016
e19b31d
refactor(test): Remove unnecessary `noSuchMethod`
Jan 12, 2016
90b3502
ci(circle config): add a circle CI config
alexeagle Jan 15, 2016
9b3a548
docs(template_parser.ts): typo
lina Jan 13, 2016
e7081b8
chore: don't track size of non-bundle files
pkozlowski-opensource Jan 13, 2016
3adc472
chore(build): fix race condition for the !bundles.js.docs task
pkozlowski-opensource Jan 8, 2016
c785a1e
fix(ddc): use dynamic types in reflection typedefs
yjbanov Jan 12, 2016
a4b5cb8
build(node): split test and src compilation units
vicb Dec 23, 2015
3e65d14
fix(Dart): make some playground samples run with Dart Dev Compiler
jacob314 Jan 13, 2016
761c6d0
fix(perf): faster looseIdentical implementation
yjbanov Jan 8, 2016
a593ffa
fix(transformer): record HostBinding annotations applied to getters
vsavkin Jan 6, 2016
f7424d5
chore: track size of a "Hello world" app built with WebPack
pkozlowski-opensource Jan 8, 2016
df3074f
feat(core/application_ref): Allow asyncronous app initializers.
jteplitz Dec 20, 2015
7b66a0d
Create .cla%3A%20yes
usernamealreadyis Jan 21, 2016
b5d8f02
Merge branch 'master' into patch-11
usernamealreadyis Feb 19, 2016
118ea1e
Merge pull request #51 from angular/IgorMinar-patch-1-1
usernamealreadyis Feb 19, 2016
1b6a47a
Merge pull request #49 from usernamealreadyis/patch-11
usernamealreadyis Feb 19, 2016
9cde2d6
Merge branch 'master' into patch-9
usernamealreadyis Feb 19, 2016
5334f2d
Merge pull request #21 from angular/IgorMinar-patch-2
usernamealreadyis Feb 19, 2016
3498a4d
Merge pull request #43 from usernamealreadyis/patch-9
usernamealreadyis Feb 19, 2016
77d946a
Merge branch 'master' into kupret.inc-1
usernamealreadyis Feb 19, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(core/application_ref): Allow asyncronous app initializers.
closes angular#5929.

Closes angular#6063
  • Loading branch information
jteplitz committed Jan 21, 2016
commit df3074fdfed0e2dbac5bf26138395b79fd14de2b
54 changes: 41 additions & 13 deletions modules/angular2/src/core/application_ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,25 +217,36 @@ export class PlatformRef_ extends PlatformRef {

application(providers: Array<Type | Provider | any[]>): ApplicationRef {
var app = this._initApp(createNgZone(), providers);
return app;
if (PromiseWrapper.isPromise(app)) {
throw new BaseException(
"Cannot use asyncronous app initializers with application. Use asyncApplication instead.");
}
return <ApplicationRef>app;
}

asyncApplication(bindingFn: (zone: NgZone) => Promise<Array<Type | Provider | any[]>>,
additionalProviders?: Array<Type | Provider | any[]>): Promise<ApplicationRef> {
var zone = createNgZone();
var completer = PromiseWrapper.completer();
zone.run(() => {
PromiseWrapper.then(bindingFn(zone), (providers: Array<Type | Provider | any[]>) => {
if (isPresent(additionalProviders)) {
providers = ListWrapper.concat(providers, additionalProviders);
}
completer.resolve(this._initApp(zone, providers));
if (bindingFn === null) {
completer.resolve(this._initApp(zone, additionalProviders));
} else {
zone.run(() => {
PromiseWrapper.then(bindingFn(zone), (providers: Array<Type | Provider | any[]>) => {
if (isPresent(additionalProviders)) {
providers = ListWrapper.concat(providers, additionalProviders);
}
let promise = this._initApp(zone, providers);
completer.resolve(promise);
});
});
});
}
return completer.promise;
}

private _initApp(zone: NgZone, providers: Array<Type | Provider | any[]>): ApplicationRef {
private _initApp(zone: NgZone,
providers: Array<Type | Provider | any[]>): Promise<ApplicationRef>|
ApplicationRef {
var injector: Injector;
var app: ApplicationRef;
zone.run(() => {
Expand All @@ -259,8 +270,12 @@ export class PlatformRef_ extends PlatformRef {
});
app = new ApplicationRef_(this, zone, injector);
this._applications.push(app);
_runAppInitializers(injector);
return app;
var promise = _runAppInitializers(injector);
if (promise !== null) {
return PromiseWrapper.then(promise, (_) => app);
} else {
return app;
}
}

dispose(): void {
Expand All @@ -273,9 +288,22 @@ export class PlatformRef_ extends PlatformRef {
_applicationDisposed(app: ApplicationRef): void { ListWrapper.remove(this._applications, app); }
}

function _runAppInitializers(injector: Injector): void {
function _runAppInitializers(injector: Injector): Promise<any> {
let inits: Function[] = injector.getOptional(APP_INITIALIZER);
if (isPresent(inits)) inits.forEach(init => init());
let promises: Promise<any>[] = [];
if (isPresent(inits)) {
inits.forEach(init => {
var retVal = init();
if (PromiseWrapper.isPromise(retVal)) {
promises.push(retVal);
}
});
}
if (promises.length > 0) {
return PromiseWrapper.all(promises);
} else {
return null;
}
}

/**
Expand Down
111 changes: 102 additions & 9 deletions modules/angular2/test/core/application_ref_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ import {
AsyncTestCompleter,
fakeAsync,
tick,
inject
inject,
SpyObject
} from 'angular2/testing_internal';
import {SpyChangeDetector} from './spies';
import {ApplicationRef_, PlatformRef_} from "angular2/src/core/application_ref";
import {Injector, Provider} from "angular2/core";
import {ApplicationRef_, ApplicationRef, PlatformRef_} from "angular2/src/core/application_ref";
import {Injector, Provider, APP_INITIALIZER} from "angular2/core";
import {ChangeDetectorRef_} from "angular2/src/core/change_detection/change_detector_ref";
import {PromiseWrapper} from "angular2/src/facade/async";
import {PromiseWrapper, PromiseCompleter, TimerWrapper} from "angular2/src/facade/async";
import {ListWrapper} from "angular2/src/facade/collection";

export function main() {
Expand All @@ -33,22 +34,114 @@ export function main() {

describe("PlatformRef", () => {
describe("asyncApplication", () => {
it("should merge synchronous and asynchronous providers",
function expectProviders(injector: Injector, providers: Array<any>): void {
for (let i = 0; i < providers.length; i++) {
let provider = providers[i];
expect(injector.get(provider.token)).toBe(provider.useValue);
}
}

it("should merge syncronous and asyncronous providers",
inject([AsyncTestCompleter, Injector], (async, injector) => {
let ref = new PlatformRef_(injector, null);
let ASYNC_PROVIDERS = [new Provider(Foo, {useValue: new Foo()})];
let SYNC_PROVIDERS = [new Provider(Bar, {useValue: new Bar()})];
ref.asyncApplication((zone) => PromiseWrapper.resolve(ASYNC_PROVIDERS), SYNC_PROVIDERS)
.then((appRef) => {
var providers = ListWrapper.concat(ASYNC_PROVIDERS, SYNC_PROVIDERS);
for (var i = 0; i < providers.length; i++) {
var provider = providers[i];
expect(appRef.injector.get(provider.token)).toBe(provider.useValue);
}
expectProviders(appRef.injector, providers);
async.done();
});
}));

it("should allow function to be null",
inject([AsyncTestCompleter, Injector], (async, injector) => {
let ref = new PlatformRef_(injector, null);
let SYNC_PROVIDERS = [new Provider(Bar, {useValue: new Bar()})];
ref.asyncApplication(null, SYNC_PROVIDERS)
.then((appRef) => {
expectProviders(appRef.injector, SYNC_PROVIDERS);
async.done();
});
}));

function mockAsyncAppInitializer(completer, providers: Array<any> = null,
injector?: Injector) {
return () => {
if (providers != null) {
expectProviders(injector, providers);
}
TimerWrapper.setTimeout(() => completer.resolve(true), 1);
return completer.promise;
};
}

function createSpyPromiseCompleter(): SpyObject {
let completer = PromiseWrapper.completer();
let completerSpy = <any>new SpyObject();
// Note that in TypeScript we need to provide a value for the promise attribute
// whereas in dart we need to override the promise getter
completerSpy.promise = completer.promise;
completerSpy.spy("get:promise").andReturn(completer.promise);
completerSpy.spy("resolve").andCallFake(completer.resolve);
completerSpy.spy("reject").andCallFake(completer.reject);
return completerSpy;
}

it("should wait for asyncronous app initializers",
inject([AsyncTestCompleter, Injector], (async, injector) => {
let ref = new PlatformRef_(injector, null);

let completer = createSpyPromiseCompleter();
let SYNC_PROVIDERS = [
new Provider(Bar, {useValue: new Bar()}),
new Provider(APP_INITIALIZER,
{useValue: mockAsyncAppInitializer(completer), multi: true})
];
ref.asyncApplication(null, SYNC_PROVIDERS)
.then((appRef) => {
expectProviders(appRef.injector,
SYNC_PROVIDERS.slice(0, SYNC_PROVIDERS.length - 1));
expect(completer.spy("resolve")).toHaveBeenCalled();
async.done();
});
}));

it("should wait for async providers and then async app initializers",
inject([AsyncTestCompleter, Injector], (async, injector) => {
let ref = new PlatformRef_(injector, null);
let ASYNC_PROVIDERS = [new Provider(Foo, {useValue: new Foo()})];
let completer = createSpyPromiseCompleter();
let SYNC_PROVIDERS = [
new Provider(Bar, {useValue: new Bar()}),
new Provider(APP_INITIALIZER,
{
useFactory: (injector) => mockAsyncAppInitializer(
completer, ASYNC_PROVIDERS, injector),
multi: true,
deps: [Injector]
})
];
ref.asyncApplication((zone) => PromiseWrapper.resolve(ASYNC_PROVIDERS), SYNC_PROVIDERS)
.then((appRef) => {
expectProviders(appRef.injector,
SYNC_PROVIDERS.slice(0, SYNC_PROVIDERS.length - 1));
expect(completer.spy("resolve")).toHaveBeenCalled();
async.done();
});
}));
});

describe("application", () => {
it("should throw if an APP_INITIIALIZER returns a promise", inject([Injector], (injector) => {
let ref = new PlatformRef_(injector, null);
let appInitializer = new Provider(
APP_INITIALIZER, {useValue: () => PromiseWrapper.resolve([]), multi: true});
expect(() => ref.application([appInitializer]))
.toThrowError(
"Cannot use asyncronous app initializers with application. Use asyncApplication instead.");
}));
});
});
}

Expand Down