Thank you all for your responses, but none of these suggestions worked for the purposes outlined in the question, but I did work on a solution and eventually got one working. Here we go:
In the service I created a new Observable called loading$
and set it up as a new BehaviorSubject<boolean>(true);
Then I created a getter:
getLoading(): Observable<boolean> {
return this.loading$;
}
Then I wrapped the HTTP call with a true
then set loading to false
in the 3rd argument on the subscription (the onCompleted function).
So the service looks like this:
import { Observable, BehaviorSubject, of } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class OrganisationsService {
private organisations$ = new BehaviorSubject<Organisation[]>([
{
[...]
}
]);
//initiate the new Loading variable via BehaviorSubject and set it to "true" from the beginning.
public loading$ = new BehaviorSubject<boolean>(true);
constructor(private http: HttpClient) {
//set the loading$ to true again just before we start the HTTP call
this.loading$.next(true);
this.http
.get(environment.apicall)
.subscribe(
//onNext method, where we get the data
(data) => this.organisations$.next(data['organisations']),
//onError method (Blank for now)
() => {},
//onComplated method, now that we have the data we can set the loading to false
() => {
this.loading$.next(false);
}
);
}
getLoading(): Observable<boolean> {
return this.loading$;
}
getList(): Observable<Organisation[]> {
return this.organisations$;
}
Notice in the subscribe method on the HTTP call, I'm adding a blank second method (This is for onError) and then in the 3rd method, I've added a function to set the loading to false: this.loading$.next(false);
. This means that Loading will now be false when the subscription is complete.
Then in my component, I get the loading$
subscription:
public loading$: Observable<boolean>;
public organisations$: Observable<Organisation[]>;
constructor(public organisationsService: OrganisationsService) {}
ngOnInit() {
this.getData();
}
async getData() {
//initially loading$ will be true because the service makes it so
this.loading$ = this.organisationsService.getLoading();
//when this completes, loading$ will be set to false via the service
this.organisations$ = this.organisationsService.getList();
}
And in my view:
<div>
<div uk-spinner *ngIf="loading$ | async"></div>
<ul class="uk-list">
<li *ngFor="let organisation of organisations$ | async">
{{ organisation.name }}
</li>
</ul>
</div>
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…