-1

in my angular application I have the following code inside a method:

let cardArray: string[] = [];

this.cardService.getCards().subscribe((cards) => {
  console.log("1", cards);

  for (const card of cards.cards) {
    cardArray.push(card.id);
  }

  console.log("2", cardArray);
});

console.log("3", cardArray);

The problem is, that 3 is logged before 1 and 2, so outside the observable the array it empty, inside it is filled. How can I achieve the data outside the observable? I need to use it at the end of my function.

Greetings!

EDIT: Added code

let cardArray: string[] = [];

this.cardService.getCards().subscribe((cards) => {
  cardArray = cards.cards;
});

return this.http.post<Object>(
  url,
  {
    cards: cardArray // <-- here the array is empty
  },
  {
    headers: headers
  }
);
lrefopam
  • 511
  • 1
  • 5
  • 22

1 Answers1

0

You need to refactor your code. It should be more like:

this.cardService.getCards()
.pipe(
   mergeMap((cards) => {
      return this.http.post<Object>(
        url,
       {
          cards: cards
       },
       {
          headers: headers
       }
     );
   })
)
.subscribe();

Here I'm using RXJS mergeMap to pipe the result of the first observable into the second. Note this is STILL async so you can't just return the result. If you want to consume this higher up I'd suggest something more like:

function postCards(): Observable<Object> {
   return this.cardService.getCards()
    .pipe(
       mergeMap((cards) => {
         return this.http.post<Object>(
            url,
            {
              cards: cards
            },
           {
              headers: headers
           }
        );
     })
   );

}


postCards().subscribe();

You should read more about RXJS operators


Is there a way to get create an array only with the IDs coming from the getCards method in this example

Well, yes and no. You should read How do I return the response from an asynchronous call?. Basically your thinking about it wrong. Don't think synchronously, you need to start thinking async.

Embrace the asynchronous nature of JavaScript! While certain asynchronous operations provide synchronous counterparts (so does "Ajax"), it's generally discouraged to use them, especially in a browser context.

Why is it bad do you ask?

JavaScript runs in the UI thread of the browser and any long-running process will lock the UI, making it unresponsive. Additionally, there is an upper limit on the execution time for JavaScript and the browser will ask the user whether to continue the execution or not.

There are various async solutions to your problem, the right one will depend on what you actually want to do with this array.

Liam
  • 27,717
  • 28
  • 128
  • 190