0

I am trying to iterate one of my HTTP get() call. It doesn't work properly. I don't know in Angular 6 how can work HTTP method in for loop. Another issue is that If I omit the for loop then the rxjs delay() function doesn't work.

getRoleOftheUser() {

   for ( let i = 0; i < this.arr.length; i++) {
       return  this.http.get<any>(`${this.baseURL}/aaa/groups/${this.arr[i]}/effectiveRolesByUser`)
        .pipe(map(res => res) , delay(5000) ).subscribe(result => console.log(result));
        }
    }

This is not an asynchronous javaScript issue. It's all about rxjs looping. Does anyone please guide me how I can iterate HTTP call in for loop in Angular 6? Thanks

Riyad
  • 339
  • 4
  • 10
  • *Side Note* - Change your server API so that you only need to make one call. Making calls in a loop with a set of known parameters (ie. parameters not dependent on the result of each successive call) is bad design because 1) there are a limited number of http requests that can be made at any one time concurrently (number is browser dependent), you are creating a chatty application, you are adding server overhead, and you are adding lag/delay (slowest part of an app is anything it has to do externally). – Igor Sep 26 '18 at 18:15
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Igor Sep 26 '18 at 18:17
  • See the proposed duplicate for how to do it though (sometimes you do not have source control over the end you are integrating with). Learn how to use asynchronous calls in javascript and then apply that to getting a combined result set from `httpClient`. – Igor Sep 26 '18 at 18:18

1 Answers1

1

Why not taking advantage of rxjs' power? Something like this

import { of } from 'rxjs';
import { concatMap, delay } from 'rxjs/operators';

.
.
.
getRoleOftheUser() {
  if (this.arr.length > 0)
    of(...this.arr)
      .pipe(
        concatMap(item => this.http.get<any>(`${this.baseURL}/aaa/groups/${item}/effectiveRolesByUser`)),
        delay(5000)
      )
      .subscribe(result => console.log(result));
}
.
.
.
Trash Can
  • 6,608
  • 5
  • 24
  • 38
  • Thanks a lot man. You are SuperMan. You saved me. Unfortunately, the first render of that component is not working. whenever I changed the component it's added the same value in my arr[] and then the getRoleOftheUser() is worked. And everytime I changed the component it's pushing the duplicate value of that arr[] array. Do you have any Solution SuperMan? Please – Riyad Sep 26 '18 at 18:30
  • Before pushing a new item into your array, surround it with a `if` block checking that it is not in the array before pushing, from the code, I assume that the items are all strings, so you can do something like `if (!this.arr.includes(newItem)) this.arr.push(newItem)` – Trash Can Sep 26 '18 at 18:33
  • `getUserbyToken() { const option = { params: new HttpParams().set('token', this.token) }; return this.http .get(`${this.baseURL}/auth/jwt/tokeninfo`, option) .pipe( mergeMap(res => { return this.http .get(`${this.baseURL}/aaa/users/${res.uuid}/groups`) .pipe(map(groups => groups)); }) ).subscribe(result => { for ( let i = 0; i < result.length; i++) { this.arr.push(result[i].uuid); } console.log(this.arr); }); }` – Riyad Sep 26 '18 at 18:49
  • SuperMan. This method is saving the arr[] which is some string. And my ngOnInit(){} is calling above both method. After first build of the app, the getRoleOftheUser() method does not work. Whever I changed the component url then it's called the ngOnInit() ad workes with duplicate values. – Riyad Sep 26 '18 at 18:50
  • Yeah, replace `this.arr.push(result[i].uuid);` with `if (!this.arr.includes(result[i].uuid)) this.arr.push(result[i].uuid)` – Trash Can Sep 26 '18 at 18:51
  • O Man you are the life saver. Only one question. This total process doesn't work after first build. It's work the second reload time of the component. Do you know how can I fix this Please? – Riyad Sep 26 '18 at 18:56
  • I meant that If I build with ng-serve the getRoleOftheUser() method doesn't work. After change the any component then it works. It's work after second time of ngOnInt() call – Riyad Sep 26 '18 at 19:00
  • ` getRoleOftheUser() { if (this.arr.length > 0) { of(...this.arr) .pipe( concatMap(item => this.http.get(`${this.baseURL}/aaa/groups/${item}/effectiveRolesByUser`)), delay(5000) ) .subscribe(result => console.log(result)); } }` – Riyad Sep 26 '18 at 19:19
  • I did it as you told. Probably something is problem with my side that I can't explain properly. Sorry.Man. Function is working fine but the first build it doesn't work. – Riyad Sep 26 '18 at 19:22
  • You need to be more specific "doesn't work" is too broad, what exactly does it mean. Does it throw an error? or what is the problem? – Trash Can Sep 26 '18 at 19:31
  • I watched it, but not sure if I understand correctly, so the problem is, after you click on the component, `getRoleOftheUser` is not showing any output until you toggle the switch? My question is where are you calling `getRoleOftheUser` in the component? – Trash Can Sep 26 '18 at 20:06
  • O man sorry. It's calling from my record-task-component.ts on ngOnInit() method – Riyad Sep 26 '18 at 20:14
  • At 3:58, you got an error when you click your tasks component, that could prevent the record-task component from calling `ngOnInit`, **Make sure that getRoleOftheUser is being called when you expect it to, that could the reason you don't see any output** – Trash Can Sep 26 '18 at 20:19
  • Love you man. This is the first time I got help so quickly from Stackoverflow. Your my hero.. Love you love you love you.. Thanks – Riyad Sep 26 '18 at 20:37
  • Very much glad to help, if it solves your problem, consider accepting my answer. Regarding learning rxjs, I just read the documentation – Trash Can Sep 26 '18 at 20:47
  • Hi @Dummy Can you please look this code that I have twicked a little bit. But it doesn't give my expectation value. `` – Riyad Sep 27 '18 at 18:52