1

So I am trying to do a POST request in Angular from an array. Basically, when a user selects multiple items in a list they can "unlock" each item. So the issue I am running into is how to do a POST with a forEach. I was able to do a POST with a forLoop but the issue is that when it does one POST it does not do the other one. Can someone please point out what I am doing wrong or if there is a better solution to this problem?

Here are the other Stack questions I looked through to find a possible solution:

Http request in forEach function. Angular2

Angular http post on loops

Chaining http calls in angular 2 in a for loop

component.ts

locked: Array<any> = [];
// Unlock
  unlock() {
    let observer = {
      next(data) {
        data => console.log(data)
      },
      error(error) {
        return new Error('Post Error');
      },
      complete() {
        console.log("Completed");
        // window.location.reload();
      }
    }
    // On unlock send lock data to Service for POST
    this.http.postUnlock(this.unlocked).subscribe(observer);
  }

service.ts

// POST to UNLOCK RESOURCES
  postUnlock(locked) {
    let headers = new Headers();
    headers.append( 'Content-Type', 'application/json');
    headers.append('Access-Control-Allow-Origin', '*');
    locked.forEach((lock) => {
      let newBody = JSON.stringify(lock);
      let auth = lock.AuthID;
      let form = lock.FormName;
      let options = new RequestOptions({ headers: headers, method: 'post', body: newBody });
      let newUrl = this.url + `?authid=${auth}&formname=${form}`;
      // POST to URL
      return this.http.post(newUrl, options).map(res => res.json());
    });
  }

Is it something that has to do with the Observable or is this something that can be handled with Promises?

Thank you for your help.

T. Evans
  • 959
  • 3
  • 14
  • 27
  • To be sur, you have called your service 'http' in your component? – Wandrille Oct 03 '17 at 18:57
  • @Wandrille yes I have added the service in my component and imported it from the file I do get an error Property 'subscribe' does not exist on type 'void' when I use the forEach, however, it does not produce this error with the forLoop – T. Evans Oct 03 '17 at 19:03
  • Replace `locked.forEach` by `return locked.map` ;) – maxime1992 Oct 03 '17 at 19:22
  • @Maxime So you're saying to do this? ```return locked.map((lock) => { let newBody = JSON.stringify(lock); let auth = lock.AuthID; let form = lock.FormName; let options = new RequestOptions({ headers: headers, method: 'post', body: newBody }); let newUrl = this.url + `?authid=${auth}&formname=${form}`; // POST to URL return this.http.post(newUrl, options).map(res => res.json()); });``` – T. Evans Oct 03 '17 at 19:27
  • @Maxime after changing to `return locked.map` I now have this error: TypeError: this.http.postUnlock(...).subscribe is not a function, coming from the component.ts file – T. Evans Oct 03 '17 at 19:43
  • I suspect you want `forkJoin` and not `map` or `forEach` – Pace Oct 03 '17 at 21:48

1 Answers1

6

here is a mix between what you looked for (Http request in forEach function. Angular2) and your code.

you cannot return a value from a for each it will exits the function (What does `return` keyword mean inside `forEach` function?)

hope it helps

postUnlock(locked){
  //create an array of Observables
  let allQueries = locked.map(lock => {
    let newBody = JSON.stringify(lock);
    let auth = lock.AuthID;
    let form = lock.FormName;
    let options = new RequestOptions({ headers: headers, method: 'post', body: newBody });
    let newUrl = this.url + `?authid=${auth}&formname=${form}`;
    // POST to URL
    return this.http.post(newUrl, options).map(res => res.json());
  });

  //return a new observable that will emit all the http results
  return Observable.forkJoin(allQueries)
}
Renaud T.
  • 139
  • 2
  • Yes, there are a number of ways to listen to multiple observables. `forkJoin` sounds like what you want. It will wait for all of them to complete and then emit an array of values which correspond to the **last** item emitted by each observable. It is good when you are dealing with *promise-like* observables (e.g. `Http`) which emit once and then complete. If you want to handle each item as it comes in you can use `merge` and if your observables emit multiple times there are ways to deal with combining each set of emissions (e.g. `zip` or `combineLatest`). – Pace Oct 03 '17 at 21:57