1484237749 by Unknown
Author:Unknown
Language: eng
Format: epub
Published: 2018-10-30T12:05:29+00:00
Chapter 5 List stories
map(ids => ids.slice(offset, offset + limit)),
mergeMap((ids: any[]) => combineLatest(...(ids.map
(id => this.db.object('/v0/item/' + id).valueChanges())))),
map((items: any) => ({
offset,
limit,
total: limit,
results: items,
}))
);
}
}
Alternative Model and Service Implementation
The current implementation of ItemService uses Observable operators
to watch for changes in the Firebase database and emit values. However,
some of those updates may not be necessary. When a story is updated, for example; when the score is updated; or new comments are added, a new
Items object that contains all items is emitted from the Observable<Items> object and triggers an update of the whole UI. This is because the operator combineLatest emits a new combined value when any source Observable
emits a value. This frequent UI update is not a good user experience. We can improve the performance by changing the data model.
Currently, we use Item[] in model Items to represent the items, which
means all Item objects need to be resolved asynchronously before creating the Items object for the ItemsComponent to render. This makes users wait longer than expected. We can update the model Items to use Observable<Item>[]
as the type of items; see Listing 5-44. Because each item is represented as its own Observable<Item> object, it can update itself separately. After updating the model, a new Items object is only emitted when the Observable of
this.db.list('/v0/topstories').valueChanges() emits a new array of ids.
170
Chapter 5 List stories
Listing 5-44. Updated model Items
import { Observable } from 'rxjs';
import { Item } from './Item';
export interface Items {
offset: number;
limit: number;
total?: number;
results: Observable<Item>[];
}
If we update the model, we can simplify the implementation of the
ItemService; see Listing 5-45. After slicing the original array of item ids, the operator distinctUntilChanged is used to make sure that duplicate
item ids won’t be emitted to trigger unnecessary UI updates. Then the
operator map is used to transform the array of item ids into an array of Observable<Item>.
Listing 5-45. Updated ItemService
import { Injectable } from '@angular/core';
import * as isEqual from 'lodash.isequal';
import { Observable } from 'rxjs';
import { map, distinctUntilChanged } from 'rxjs/operators';
import { Items } from '../../models/items';
import { AngularFireDatabase } from '@angular/fire/database';
@Injectable()
export class ItemService {
constructor(private db: AngularFireDatabase) {}
171
Chapter 5 List stories
load(offset: number, limit: number): Observable<Items> {
return this.db.list('/v0/topstories')
.valueChanges()
.pipe(
map(ids => ids.slice(offset, offset + limit)),
distinctUntilChanged(isEqual),
map((ids: any[]) => ids.map(id => this.db.object('/v0/
item/' + id).valueChanges())),
map((items: any) => ({
offset,
limit,
total: limit,
results: items,
}))
);
}
}
After updating the model, the implementation of ItemService can be
simplified. However, it makes the implementation of ItemComponent
complicated. As the type of the property item is changed from Item to
Observable<Item>, ItemComponent needs to subscribe to the Observable and re-render itself when a new value is emitted. This can be done using the pipe async.
The changes to model and ItemComponent are an alternative way to
implement the user story. However, this implementation violates one
fundamental principle of designing components like ItemComponent.
These components should only have pure rendering logic. The logic of
handling Observables in ItemComponent makes it hard to test. This section only provides information about potential alternative implementations.
The actual implementation of the example still uses the old model.
The aforementioned performance issue will be solved by using state
management frameworks in Chapter 6.
172
Download
This site does not store any files on its server. We only index and link to content provided by other sites. Please contact the content providers to delete copyright contents if any and email us, we'll remove relevant links or contents immediately.
Sita - Warrior of Mithila (Book 2 of the Ram Chandra Series) by Amish(53338)
The Crystal Crypt by Dick Philip K(36173)
Cat's cradle by Kurt Vonnegut(14491)
Always and Forever, Lara Jean by Jenny Han(14219)
Ready Player One by Cline Ernest(13669)
The Last by Hanna Jameson(9608)
Year One by Nora Roberts(9080)
Persepolis Rising by James S. A. Corey(8665)
The remains of the day by Kazuo Ishiguro(8076)
Red Rising by Pierce Brown(7972)
Never let me go by Kazuo Ishiguro(7950)
Dark Space: The Second Trilogy (Books 4-6) (Dark Space Trilogies Book 2) by Jasper T. Scott(7737)
The handmaid's tale by Margaret Atwood(7247)
The Circle by Dave Eggers(6646)
Frank Herbert's Dune Saga Collection: Books 1 - 6 by Frank Herbert(6443)
The Testaments by Margaret Atwood(6194)
Legacy by Ellery Kane(6192)
Pandemic (The Extinction Files Book 1) by A.G. Riddle(5999)
Six Wakes by Mur Lafferty(5621)
