Skip to content

Commit be58c6b

Browse files
jamesdanielsdavideast
authored andcommitted
fix(): Fixing Zone.js issues (#1586)
* fix(): Fixing Zone.js issues * Trying out only blocking on platformServer * yarn upgrade
1 parent f2cf159 commit be58c6b

File tree

17 files changed

+493
-1083
lines changed

17 files changed

+493
-1083
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "angularfire2",
3-
"version": "5.0.0-rc.6",
3+
"version": "5.0.0-rc.7.2-next",
44
"description": "The official library of Firebase and Angular.",
55
"private": true,
66
"scripts": {

src/auth/auth.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { FirebaseAuth, User } from '@firebase/auth-types';
22
import { FirebaseOptions } from '@firebase/app-types';
3-
import { Injectable, Inject, Optional, NgZone } from '@angular/core';
3+
import { Injectable, Inject, Optional, NgZone, PLATFORM_ID } from '@angular/core';
44
import { Observable } from 'rxjs/Observable';
5-
import { observeOn } from 'rxjs/operator/observeOn';
65

76
import { FirebaseAppConfig, FirebaseAppName, _firebaseAppFactory, FirebaseZoneScheduler } from 'angularfire2';
87

@@ -31,9 +30,10 @@ export class AngularFireAuth {
3130
constructor(
3231
@Inject(FirebaseAppConfig) config:FirebaseOptions,
3332
@Optional() @Inject(FirebaseAppName) name:string,
33+
@Inject(PLATFORM_ID) platformId: Object,
3434
private zone: NgZone
3535
) {
36-
const scheduler = new FirebaseZoneScheduler(zone);
36+
const scheduler = new FirebaseZoneScheduler(zone, platformId);
3737
this.auth = zone.runOutsideAngular(() => {
3838
const app = _firebaseAppFactory(config, name);
3939
return app.auth();

src/core/angularfire2.ts

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { InjectionToken, NgZone } from '@angular/core';
2-
import { Subscription } from 'rxjs/Subscription';
32
import { Observable } from 'rxjs/Observable';
3+
import { Subscription } from 'rxjs/Subscription';
44
import { queue } from 'rxjs/scheduler/queue';
5+
import { isPlatformServer } from '@angular/common';
6+
import { observeOn } from 'rxjs/operator/observeOn';
57

68
import firebase from '@firebase/app';
79
import { FirebaseApp, FirebaseOptions } from '@firebase/app-types';
810

911
import 'zone.js';
1012
import 'rxjs/add/operator/first';
11-
import { Subscriber } from 'rxjs/Subscriber';
12-
import { observeOn } from 'rxjs/operator/observeOn';
1313

1414
export const FirebaseAppName = new InjectionToken<string>('angularfire2.appName');
1515
export const FirebaseAppConfig = new InjectionToken<FirebaseOptions>('angularfire2.config');
@@ -18,25 +18,32 @@ export const FirebaseAppConfig = new InjectionToken<FirebaseOptions>('angularfir
1818
export const RealtimeDatabaseURL = new InjectionToken<string>('angularfire2.realtimeDatabaseURL');
1919

2020
export class FirebaseZoneScheduler {
21-
constructor(public zone: NgZone) {}
21+
constructor(public zone: NgZone, private platformId: Object) {}
2222
schedule(...args: any[]): Subscription {
2323
return <Subscription>this.zone.runGuarded(function() { return queue.schedule.apply(queue, args)});
2424
}
2525
// TODO this is a hack, clean it up
2626
keepUnstableUntilFirst<T>(obs$: Observable<T>) {
27-
return new Observable<T>(subscriber => {
28-
const noop = () => {};
29-
const task = Zone.current.scheduleMacroTask('firebaseZoneBlock', noop, {}, noop, noop);
30-
obs$.first().subscribe(() => this.zone.runOutsideAngular(() => task.invoke()));
31-
return obs$.subscribe(subscriber);
32-
});
27+
if (isPlatformServer(this.platformId)) {
28+
return new Observable<T>(subscriber => {
29+
const noop = () => {};
30+
const task = Zone.current.scheduleMacroTask('firebaseZoneBlock', noop, {}, noop, noop);
31+
obs$.first().subscribe(() => this.zone.runOutsideAngular(() => task.invoke()));
32+
return obs$.subscribe(subscriber);
33+
});
34+
} else {
35+
return obs$;
36+
}
3337
}
3438
runOutsideAngular<T>(obs$: Observable<T>): Observable<T> {
35-
const outsideAngular = new Observable<T>(subscriber => {
39+
return new Observable<T>(subscriber => {
3640
return this.zone.runOutsideAngular(() => {
37-
return obs$.subscribe(subscriber);
41+
return obs$.subscribe(
42+
value => this.zone.run(() => subscriber.next(value)),
43+
error => this.zone.run(() => subscriber.error(error)),
44+
() => this.zone.run(() => subscriber.complete()),
45+
);
3846
});
3947
});
40-
return observeOn.call(outsideAngular, this);
4148
}
4249
}

src/database-deprecated/firebase_list_factory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ function firebaseListObservable(ref: database.Reference | DatabaseQuery, {preser
187187
});
188188

189189
// TODO: should be in the subscription zone instead
190-
return observeOn.call(listObs, new FirebaseZoneScheduler(new NgZone({})));
190+
return observeOn.call(listObs, new FirebaseZoneScheduler(new NgZone({}), {}));
191191

192192
}
193193

src/database-deprecated/firebase_object_factory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ export function FirebaseObjectFactory (
2222
}, ref);
2323

2424
// TODO: should be in the subscription zone instead
25-
return observeOn.call(objectObservable, new FirebaseZoneScheduler(new NgZone({})));
25+
return observeOn.call(objectObservable, new FirebaseZoneScheduler(new NgZone({}), {}));
2626
}

src/database/database.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ describe('AngularFireDatabase', () => {
4242
});
4343

4444
it('should accept a Firebase App in the constructor', () => {
45-
const __db = new AngularFireDatabase(app.options, app.name, null!, zone);
45+
const __db = new AngularFireDatabase(app.options, app.name, null!, {}, zone);
4646
expect(__db instanceof AngularFireDatabase).toEqual(true);
4747
});
4848

src/database/database.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Injectable, Inject, Optional, NgZone } from '@angular/core';
1+
import { Injectable, Inject, Optional, NgZone, PLATFORM_ID } from '@angular/core';
22
import { FirebaseDatabase } from '@firebase/database-types';
33
import { PathReference, DatabaseQuery, DatabaseReference, DatabaseSnapshot, ChildEvent, ListenEvent, QueryFn, AngularFireList, AngularFireObject } from './interfaces';
44
import { getRef } from './utils';
@@ -17,9 +17,10 @@ export class AngularFireDatabase {
1717
@Inject(FirebaseAppConfig) config:FirebaseOptions,
1818
@Optional() @Inject(FirebaseAppName) name:string,
1919
@Optional() @Inject(RealtimeDatabaseURL) databaseURL:string,
20+
@Inject(PLATFORM_ID) platformId: Object,
2021
zone: NgZone
2122
) {
22-
this.scheduler = new FirebaseZoneScheduler(zone);
23+
this.scheduler = new FirebaseZoneScheduler(zone, platformId);
2324
this.database = zone.runOutsideAngular(() => {
2425
const app = _firebaseAppFactory(config, name);
2526
return app.database(databaseURL || undefined);

src/database/list/audit-trail.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ import 'rxjs/add/operator/withLatestFrom';
1010
import 'rxjs/add/operator/map';
1111

1212
export function createAuditTrail(query: DatabaseQuery, afDatabase: AngularFireDatabase) {
13-
return (events?: ChildEvent[]) => afDatabase.scheduler.keepUnstableUntilFirst(auditTrail(query, events));
13+
return (events?: ChildEvent[]) => afDatabase.scheduler.keepUnstableUntilFirst(
14+
afDatabase.scheduler.runOutsideAngular(
15+
auditTrail(query, events)
16+
)
17+
);
1418
}
1519

1620
export function auditTrail(query: DatabaseQuery, events?: ChildEvent[]): Observable<SnapshotAction[]> {

src/database/list/create-reference.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,21 @@ export function createListReference<T>(query: DatabaseQuery, afDatabase: Angular
1515
remove: createRemoveMethod(query.ref),
1616
snapshotChanges(events?: ChildEvent[]) {
1717
const snapshotChanges$ = snapshotChanges(query, events);
18-
return afDatabase.scheduler.keepUnstableUntilFirst(snapshotChanges$);
18+
return afDatabase.scheduler.keepUnstableUntilFirst(
19+
afDatabase.scheduler.runOutsideAngular(
20+
snapshotChanges$
21+
)
22+
);
1923
},
2024
stateChanges: createStateChanges(query, afDatabase),
2125
auditTrail: createAuditTrail(query, afDatabase),
2226
valueChanges<T>(events?: ChildEvent[]) {
2327
const snapshotChanges$ = snapshotChanges(query, events);
24-
return afDatabase.scheduler.keepUnstableUntilFirst(snapshotChanges$)
25-
.map(actions => actions.map(a => a.payload.val()));
28+
return afDatabase.scheduler.keepUnstableUntilFirst(
29+
afDatabase.scheduler.runOutsideAngular(
30+
snapshotChanges$
31+
)
32+
).map(actions => actions.map(a => a.payload.val()));
2633
}
2734
}
2835
}

src/database/list/state-changes.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ import { DataSnapshot } from '@firebase/database-types';
88
import { AngularFireDatabase } from '../database';
99

1010
export function createStateChanges(query: DatabaseQuery, afDatabase: AngularFireDatabase) {
11-
return (events?: ChildEvent[]) => afDatabase.scheduler.keepUnstableUntilFirst(stateChanges(query, events));
11+
return (events?: ChildEvent[]) => afDatabase.scheduler.keepUnstableUntilFirst(
12+
afDatabase.scheduler.runOutsideAngular(
13+
stateChanges(query, events)
14+
)
15+
);
1216
}
1317

1418
export function stateChanges(query: DatabaseQuery, events?: ChildEvent[]) {

0 commit comments

Comments
 (0)