I'm building an Angular app to show my website's articles and votes and I want to show them sorted based on their vote. I can retrieve votes making http calls, in particular:
- I have to make a http call to retrieve the list of categories and the list of their IDs (I often add categories in my website so I need to update my app)
- I have to use these IDs to make one http call for each ID to get the list of articles of that particular category.
- Every article has an ID, I have to store every ID to make another one http call for each article ID.
- Finally every n.3) response object has a 'users_vote' property. I need then to build an array to merge all the votes and then sort the array. Then I'll show the array on HTML code.
I don't understand how to chain promises so the code is just to clarify what I mean. I also know that it's really 'tricky' but I can't change anything server side at the moment and I have to deal with this.
ngOnInit() {
this.getCategories()
.then((res) => {
this.getIds(res)
.then((res) => {
this.getArticlesList(res)
.then((res) => {
this.mergeArticlesList(res)
})
})
})
}
// 1) getCategories() to get the list
getCategories() {
var promise = new Promise((resolve) => {
this.myService.getCategoriesList()
.subscribe((res) => {
this.categories = res;
resolve(this.categories);
})
})
return promise;
}
// 2) getCategoriesIDs(res) to get their IDs and store them in this.ids
getCategoryIDs(res) {
var promise = new Promise((resolve) => {
for (let i=0; i < Object.keys(res).length; i++) {
this.ids[i] = res[i+1]['id']
}
resolve(this.ids)
})
return promise;
}
// 3) getArticlesList(res) to get the list of articles of each category
getArticlesList(res) {
var promise = new Promise((resolve) => {
for (let i=0; i < Object.keys(res).length; i++) {
this.myService.getArticlesOfCategory(res[i])
.subscribe((res) => {
this.allarticleslist[i] = res;
})
}
resolve(this.allarticleslist)
})
return promise;
}
// 4) mergeArticleIds(res) to create another array of ids (this time is // the list of articles' IDs
mergeArticleIds(res) {
console.log("Start merging with:")
console.log(res)
console.log(res.length)
console.log(Object.keys(res).length)
for (let i=1; i < Object.keys(res).length -1; i++) {
for (let _i=0; _i < res[i]['reviews'].length; _i++) {
this.mergedArticles = res[i]['reviews'][_i]['id'] }
}
return this.mergedArticles
}
// 5) getArticle(res) to get the article with that particular ID
// With this http call I finally can get 'article_vote' and I have to
// save this value in order to sort the array.
// It has to return the array sorted
getArticle(res) {
// ??
}
}
It's not working because console.log(res.length) returns 0, so for loop doesn't even start. I know I have to deal with asynchronous operations timing too, but I don't know how to do it.
EDIT: adding getCategoriesList() from myService:
getCategoriesList(): Observable<any[]> {
let url = 'myurl';
return this.httpClient.get(url)
}
EDIT2: adding getCategoriesList()'s http.get response:
{"5":{"description":"","title":"SOCCER""term_id":280,"room_name":"SOCCER"},
"4":{"description":"","title":"NFL","term_id":281,"room_name":"NFL"},
"3":{"description":"","title":"MLB","term_id":282,"room_name":"MLB"},
"2":{"description":"","title":"NHL","term_id":283,"room_name":"NHL"},
"6":{"description":"","title":"TENNIS","term_id":284,"room_name":"TENNIS"},
"1":{"description":"","title":"F1","term_id":285,"room_name":"F1"}}