Home > Enterprise >  Extracting data from subscribe() method
Extracting data from subscribe() method

Time:02-26

I don't really know how to extract the values from the subscribe() method.

getMessages(): any {
  this.gatewayMessagesState$.subscribe(data => data.gatewayMessages
    .get(this.gatewayId)
    ?.list
    .map(Message => Message.message));
  }

gatewayMessagesState is an initial state that contains some data. gatewayMessages is a map with gatewayIds as keys and arrays of Message objects as values. Message has message field that's just a string. I would like to extract an array of messages for a given id. How can I do that?

CodePudding user response:

I this you want to retrieve the data as an observable of messages as string, you can define the function return as this and using pipe and map operatoes from rxjs,this is code below is my proposition

getMessages(): observable<string[]>{
  return this.gatewayMessagesState$.pipe(map((data) =>
 data.filter((f) => f.gatewayMessages.id ===this.gatewayId)),
map(item => item.message));

  }

CodePudding user response:

What you probably want to do is to populate another Observable with the data so that you can access it elsewhere in your project without the need for calling the API more than once.
To do this, you create what is known as a Subject (in this case a BehaviorSubject) and you can populate that with data when your API call returns a response.
Then, in order to access this data elsewhere, you can create a "get" function to return the Subject (which is itself an Observable) whenever you need the data.
Here is an example:

my - data.service.ts

myData: BehaviorSubject < number > = new BehaviorSubject < number > (0);
callApi() {
    this.dbService.get('apiUrl').subscribe(
        (data) = > this.myData.next(data) // Assuming data is a 'number'
    );
}
getMyData() {
    return this.myData.asObservable();
}

Now to use this in a component:

this.myService.getMyData().subscribe(
    (data) = > {
        /* Use the value from myData observable freely */
    }
);

Or you could rely on the Angular async pipe (which is a very convenient method for dealing with observables in your code).

CodePudding user response:

You are not specifying if getMessages is in a service, component... in any case, I suggest returning the Observable without subscribing to it in the getMessages function

// this function could be anywhere
getMessages(): Observable<string[]> {
  return this.gatewayMessagesState$.pipe(
    map((data) => data.gatewayMessages.get(this.gatewayId)),
    map((yourMap) => yourMap?.list.map((theMessage) => theMessage.message))
  );
}

Now, if you need to extract this value, either from a component, a service, etc... then, just call this function and then subscribe to get the result

Let's say getMessages is in a service file for example

Your component

constructor(private theService: YourService) {}
 
anotherFunction() {
  this.theService.getMessages().subscribe((myMessages) => console.log(myMessages));
}

Or let the async pipe subscribe to this observable

Your component

messages$!: Observable<string[]>

constructor(private theService: YourService) {}

anotherFunction() {
  this.messages$ = this.theService.getMessages()
}

Your component html

<ng-container *ngIf="messages$ | async as messages">
  <div *ngFor="let message of messages">
    <p>{{ message }}</p> 
  </div>
</ng-container>
  • Related