Reputation: 21
Here I am getting data from storage
sendRequest() {
this.userservise.getAllUsers(...)
console.log("bedore")
this.query.selectAll().subscribe(users => {
console.log("inside")
this.users = users
})
console.log("after")
}
Here I write them in storage
getAllUsers(...) {
var url = ...
return this.http.get<User[]>(url, { withCredentials: true }).subscribe(u => {
this.store.set(u)
});
}
The strange behavior is that the "insede" function fires many times, with one more time on each new request. look scan
The query to the database is always sent one, as it should be. Also, if you exclude the Akita, everything will work fine.
sendRequest() {
this.userservise.getAllUsers(...).subscribe(users => {
this.users = users
})
}
getAllUsers(...): Observable<User[]> {
var url = ...
return this.http.get<User[]>(url, { withCredentials: true })
}
Store:
import { Injectable } from '@angular/core';
import { EntityState, EntityStore, StoreConfig } from '@datorama/akita';
import { User } from '../user';
export interface TodosState extends EntityState<User, number> { }
@Injectable({
providedIn: 'root'
})
@StoreConfig({ name: 'todos' })
export class TodosStore extends EntityStore<TodosState> {
constructor() {
super() ;
}
}
Query:
import { Injectable } from "@angular/core";
import { QueryEntity } from "@datorama/akita";
import { TodosState, TodosStore } from "./store";
@Injectable({
providedIn: 'root'
})
export class TodosQuery extends QueryEntity<TodosState> {
constructor(protected override store: TodosStore) {
super(store);
}
}
What could be the problem?
Upvotes: 1
Views: 679
Reputation: 643
I think there are a few things wrong with what you're doing. I think you're using RxJS observable in some odd manner which might be causing this. I can't tell what's wrong until I have a look at the complete code but maybe my example will help you understand the appropriate way of doing it.
In your service, you should have a getUsers method as follows:
public getUsers(): Observable<User[]> {
var url = "";
return this.http.get<User[]>(url).pipe(tap((data) => {
this._store.add(data);
}));
}
Then in your component.ts file, do the follows:
public readonly todos$ = this._query.selectAll();
And finally, in the HTML template, you can use it as follows:
<ol>
<li *ngFor="let user of todos$ | async">
{{ user.name }}
</li>
</ol>
Incase you want to access properties of the User[], you can do it as follows in the HTML:
<p *ngIf="todos$ | async as todos">
You have: {{ todos.length }}. <br />
JSON: {{ todos | json }}
</p>
You can also see a running example of the above on Stackblitz.
Update:
I think I also realized, what you're doing wrong. Below is the example that you shared in OP.
sendRequest() {
this.userservise.getAllUsers(...)
console.log("bedore")
this.query.selectAll().subscribe(users => {
console.log("inside")
this.users = users
})
console.log("after")
}
The reason why you're getting inside one more time than the last time, every time is because you're subscribing to a new observable every time without discarding the old one. Your problem can be fixed as follows but it still won't be a recommended approach.
sendRequest() {
this.userservise.getAllUsers(...)
console.log("bedore")
this.query.selectAll()
.pipe(first())
.subscribe(users => {
console.log("inside")
this.users = users
})
console.log("after")
}
Upvotes: 0