Reputation: 857
I use the app service to listen for pouchdb changes:
init() {
const pouch = new PouchDB('app_data', {});
const remoteDB = new PouchDB('http://xx.xx.xx.xx:35986/app_data', {
skip_setup: true,
auto_compaction: true,
auth: {
username: 'root',
password: 'root'
}
});
const sync = pouch.sync(remoteDB, {
live: true,
retry: true
}).on('change', (info) => {
this.facilityProtoService.update();
...
and another service to send data to the view:
@Injectable()
export class FacilityProtoService {
constructor() {}
private pouch = new PouchDB('app_data', {});
private facilityProtoStore = new Subject<any>();
public facilityProto$ = this.facilityProtoStore.asObservable();
public update() {
console.log('[facilityProto] update');
this.pouch.get('facilities')
.then((res:any) => this.facilityProtoStore.next(res.structure))
}
}
component looks like:
@Component({
selector: 'zpa-facility-designer',
template: `
<p>facility-designer works!</p>
<ng-container *ngFor="let key of test$ | async, trackBy: trackByFn">
{{ key }}<br>
</ng-container>
`
})
export class FacilityDesignerComponent implements OnInit {
test$: any;
constructor(
private facilityProtoService: FacilityProtoService
) {}
ngOnInit() {
this.test$ = this.facilityProtoService.facilityProto$.pipe(tap(i => console.log(Object.keys(i))), map(i => Object.keys(i)))
}
trackByFn(index, item) {
return index;
}
}
The data is always shown correctly in tap operator, but view did not update.
As soon as I add an interval function to the constructor of the app service all works perfectly, the view updates correctly.
constructor(
private facilityProtoService: FacilityProtoService
) {
console.log('app service');
setInterval(() => {}, 1000);
}
Both services are singletons and the app service init is triggered by app_initializer.
Any ideas why it works with interval? And only in component and not in the component view?
Edit: It also works when the interval function is in the ngOnInit hook of the component.
Edit 2:
I have make the example much smaller:
init() {
this.changes.next(5);
setTimeout(() => {
this.changes.next(6)
});
this.pouch = new PouchDB('app', {});
const remoteDB = new PouchDB('http://127.0.0.1:5984/app', {
skip_setup: true,
auth: {
username: 'root',
password: 'root'
}
});
const sync = this.pouch
.sync(remoteDB, {
live: true,
retry: true
})
.on('change', () => {
this.changes.next(7)
})
}
value 5 and 6 are correctly displayed in view... 7 only in component.
Upvotes: 0
Views: 67
Reputation: 433
I would try with something like this to make sure u get a new reference:
test$: BehaviourSubject<any> = new BehaBehaviourSubject(null);
and then:
this.facilityProtoService.facilityProto$.pipe.subscribe(tap(i => { console.log(Object.keys(i));
test$.next(Object.keys(i);
});
Upvotes: 1
Reputation: 44295
It looks like the syntax is a little off. Check your console output for errors. Try
<ng-container *ngIf="test$ | async as tests">
<ng-container *ngFor="let key of tests; trackBy: trackByFn">
{{ key }}<br>
</ng-container>
</ng-container>
Upvotes: 1