简体   繁体   中英

Angular 4 async data storage

I'm creating a testing application that has 1000s of questions hosted on firebase. To prevent downloading the questions multiple times, I've implemented a questions service where in the constructor I download the questions:

this.db.list("questions/", { preserveSnapshot: true}).subscribe(snapshots => {...}

This downloads the questions and pushes them to a questions array so that I don't have to re download until the next session. I also have a function to serve the questions:

getQuestion(){
    return this.questions[0];
}

However, because of the asynchronous nature of firebase, often times the data is not yet downloaded before getQuestion() is called, so it returns undefined.

Is there a proper way to implement this data store type pattern in angular, and make sure the async call in the constructor finishes before getQuestion() gets called?

I've tried adding a variable ready , initializing it to false, and setting it to true when the async call returns. Then, getQuestions() is modified to look like:

getQuestion(){
    while(!this.ready()){}
    return this.questions[0];
}

However this just causes the app to hang.

It's almost never necessary to use preserveSnapshot . Not having to worry about snapshots is one of the main benefits of using AngularFire. Just write this.db.list(PATH).subscribe(list => .

You're confusing "downloading" with "subscribing". It is hardly ever a good idea to subscribe inside a service, and store the data locally--you'll never be exactly sure when the subscribe handler has run, as you have found.

Instead, the service should provide an observable, which consumers--usually components-will consume. Those consumers can subscribe to the observable and do whatever they want, include storing the data statically, or, preferably, you can subscribe to the observable directly within a template using the async pipe.

The general rule is to subscribe as late as possible--ideally in the template. Write your code as a set of observables which you map and filter and compose.

Firebase caches results and in general you don't need to worry about caching yourself.

Call getQuestion() function after Data from FireBase was downloaded. Use blow code:

this.db.list("questions/").subscribe(list => {...} //etc

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM