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.

6
  • To be sur, you have called your service 'http' in your component? Commented Oct 3, 2017 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 Commented Oct 3, 2017 at 19:03
  • Replace locked.forEach by return locked.map ;) Commented Oct 3, 2017 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()); }); Commented Oct 3, 2017 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 Commented Oct 3, 2017 at 19:43

1 Answer 1

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)
}
Sign up to request clarification or add additional context in comments.

1 Comment

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).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.