I am trying to learn @ngrx/data by creating simple TODO app
I created simple ToDoDataService to override default HTTP
@Injectable()
export class TodosDataService extends DefaultDataService<Todo> {
constructor(httpClient: HttpClient, httpUrlGenerator: HttpUrlGenerator) {
super('Todo', httpClient, httpUrlGenerator);
}
getAll(): Observable<Array<Todo>> {
console.log('asfsfsfsf')
return this.http.get('https://jsonplaceholder.typicode.com/todos')
.pipe(
map((res: any) => res)
);
}
getWithQuery(query): Observable<Array<any>> {
console.log('asfsfsfsf', query);
return this.http.get(`https://jsonplaceholder.typicode.com/todos?${query}`)
.pipe(
map((res: any) => res)
);
}
}
In the route-resolver i am doing like this
@Injectable()
export class TodosResolver implements Resolve<boolean> {
constructor(private todoService: TodoEntityService) {
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.todoService.loaded$
.pipe(
tap(loaded => {
if (!loaded) {
this.todoService.getAll();
}
}),
filter(loaded => !!loaded),
first()
);
}
}
This is working fine and store/entities is updated
But in my component I am doing like this
export class HomeComponent implements OnInit {
loading$: Observable<boolean>;
todos$: Observable<Todo[]>;
constructor(
private todoService: TodoEntityService
) { }
ngOnInit() {
console.log('dsdf');
this.todos$ = this.todoService.entities$
.pipe(
tap(todos => {
console.log(todos);
this.loadMore();
console.log(todos);
}),
map((todos: any) => todos),
first()
);
}
loadMore() {
this.todoService.getWithQuery('_start=20&_limit=5');
}
}
Here API is calling but entities is still showing old data. Not sure what i am doing wrong,
Please help
Welcome on @ngrx/data.
I suggest you to review the code snippet inside ngOnInit.
Here, you call loadMore method which implies a new Http request, each time the collection is updated.
Your code should look like this:
ngOnInit() {
// keep a local reference to observable of entities
this.todos$ = this.todoService.entities$;
// request a first load on view init
this.loadMore();
}
In this way, the code inside TodosResolver is not really needed.
If you want to implement a Load More feature, you should react to another event (like scrolling or a click on button), and then call again loadMore.
Your observables like entities$ or loaded$ are just pipelines of data, and you shouldn't dispatch action when new values are emitted.
If really needed, prefer to write a @ngrx/effect, it's done for that.
If you want to change the data or its format, you can use the Observable pipe for that, but not for calling a new action.
For example, this is ok:
this.todos$ = this.todoService.entities$.pipe(
map(entities => entities.map(entity => ({
...entity,
authorName: entity.authorFirstname + ' ' + entity.authorLastName
})));
);
Hope my answer is clear and will help you a little.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With