Reputation: 595
I'll have an angular service with a function getTimeLinePosts
to get JSON from a server. In the timeline-page.ts component I'll subscribe to that function. When sending a request to the server I'll need to send the date of the previous cached response (using ionic cache) to check if there is new data. The problem is the const date
returns a promise instead of a value. I'll can't use async getTimeLinePosts
because of the subscribe in de timeline-page.ts. Suggestions how I'll can wait for the date before returning the loadFromDelayedObservable
?
getTimelinePosts(
limit: number = 25,
offset: number = 0,
type: string = "",
group: number = null
) {
let cacheKey = `api/timeline?l=${limit}&o=${offset}&t=${type}&g=${group}`;
// How wait for this value before fire request
const date = this.getCachedItem(cacheKey);
let request = this.http.post(cacheKey, { headers: HEADER.headers , params: JSON.stringify({ dateUpdated: date }) } );
let groupKey = "timeline";
let ttl = 60 * 60 * 1;
let delayType = "none";
return this.cache
.loadFromDelayedObservable(url, request, groupKey, ttl, delayType)
.pipe(map((result) => result));
}
async getCachedItem(cacheKey){
let data = await this.cache.getItem(cacheKey)
.catch(() => {
console.log("Oh no! My promise is expired or doesn't exist!");
});
return await data.data.dateUpdated;
}
this.TimelineService.getTimelinePosts(limit, offset, type, group).subscribe(
(data) => {
this.setTimelineData(data);
}
);
Upvotes: 0
Views: 242
Reputation: 31105
This looks like a typical case of combining observables and promises. I'd stick with converting the promise to an observable so we can leverage many of it's advantages.
You could use RxJS from
function to convert the promise to an observable. Then you could use a higher order mapping operator like switchMap
to map from one observable to another.
Try the following
import { from } from 'rxjs';
import { switchMap } from 'rxjs/operators';
getTimelinePosts(
limit: number = 25,
offset: number = 0,
type: string = "",
group: number = null
) {
let cacheKey = `api/timeline?l=${limit}&o=${offset}&t=${type}&g=${group}`;
return from(this.getCachedItem(cacheKey)).pipe(
switchMap(date => {
let request = this.http.post(cacheKey, { headers: HEADER.headers, params: JSON.stringify({ dateUpdated: date }) });
let groupKey = "timeline";
let ttl = 60 * 60 * 1;
let delayType = "none";
return this.cache
.loadFromDelayedObservable(url, request, groupKey, ttl, delayType)
.pipe(map((result) => result));
})
);
}
Upvotes: 1
Reputation: 2593
You can use observables - specifically mergeMap/flatMap, this is similar to sending a two requests one after the other, where the second one depends on the first:
getTimelinePosts(
limit: number = 25,
offset: number = 0,
type: string = "",
group: number = null
) {
let cacheKey = `api/timeline?l=${limit}&o=${offset}&t=${type}&g=${group}`;
this.getCachedItem(cacheKey)
.pipe(mergeMap((date) => {
let request = this.http.post(cacheKey, { headers: HEADER.headers , params: JSON.stringify({ dateUpdated: date }) } );
let groupKey = "timeline";
let ttl = 60 * 60 * 1;
let delayType = "none";
return this.cache
.loadFromDelayedObservable(url, request, groupKey, ttl, delayType)
.pipe(map((result) => result));
}));
}
Upvotes: 0