I have a data provider that I’m injecting into multiple tabs. It’s getData function is used to load data, it uses a flag to determine if it’s already loaded, but it is getting called multiple time before the loaded flag is set. So I thought I’d have a loading flag, and if set, wait for the other loading to finish, then resolve. But I do not know how to do that with a Promise.
I’m new to javascript and promises.
Thanks,
Jon
getData(): Promise<DataModel> {
return new Promise(resolve => {
if (this.loaded) {
console.log('data already loaded');
resolve(this.myData);
}
if (this.loading) {
console.log('loading data');
//
// wait for other load to finish, then resolve
//
}
console.log('loading data');
this.loading = true;
this.storage.get('ptt-data').then((data) => {
this.myData = DataModel.fromJSON(data);
this.loaded = true;
this.loading = false;
resolve(this.myData);
});
You are creating way too many unnecessary things. You don’t need to make a new Promise, you don’t want either loading or loaded flags, and you don’t want multiple code paths. All of those things only provide places for bugs to live. In fact, I would argue you might not even want getData() to be a function, since calling it multiple times won’t ever get you anything new.
I would refactor this to only expose data as a Promise<DataModel>:
Personally, I don’t like things like DataModel needing special methods like fromJSON(). I just make them interfaces, in which case that last line isn’t even needed. I assume you have some reason for doing unusual unmarshalling logic on these objects, and if that’s true, I would consider moving it out of DataModel and into the provider service, allowing DataModel to just be an interface.
I’m all for simpler. In trying your code, I’m getting the following:
Typescript Error
Argument of type 'LocalForage' is not assignable to parameter of type 'string'.
D:/development/ionic/ProjectTimeTracker2/src/providers/local-data.ts
.then(() => this.storage.get('ptt-data'))
.then((json) => DataModel.fromJSON(json));
}
I’m new to Javascript in general, so I may be doing things wrong. But the reason that I have the load from json and the opposite, is that I create some mappings of the objects created using string UUID keys. But in the JSON that I save I do not want the mappings.
See if that works. Oh, and please stop using any. data is a Promise<DataModel>. I would also get rid of myData, as having the same thing in two places is asking for trouble.
I think I’m starting to understand. I replaced the myData usage in the tabs with the promise. So I’m making progress learning. Still get an error on that syntax:
Typescript Error
Argument of type '(json: string) => DataModel' is not assignable to parameter of type '(value: LocalForage) => DataModel | PromiseLike<DataModel>'. Types of parameters 'json' and 'value' are incompatible. Type 'LocalForage' is not assignable to type 'string'.
D:/development/ionic/ProjectTimeTracker2/src/providers/local-data.ts
.then(() => this.storage.get('ptt-data'))
.then((json: string) => DataModel.fromJSON(json));
Definitely something in my environment. I did a ionic start ProjectTimeTracker blank. Then created a file for the 1st two classes. Saving the 2nd file got the same error on your code. Maybe I’ll reinstall ionic and see if that helps.