Manipulate and send back information from Observable in Angular

Here is an example of a scenario where I have created a service to retrieve a list of properties. Within this service, I am utilizing the map function to manipulate the response and then returning the final array as an Observable.

My question is: How can I easily obtain that final array in JSON format from the service and pass it to my component? Below is what I have accomplished thus far:

SERVICE

getPropertyList(){
    let propertyList$ : Observable<any> = this._http.get('http://localhost:3000/...');

    return propertyList$.pipe(
      map(data => {
        // perform necessary transformations
        let listArray: Array<any> = data.response.dataset;
        listArray.forEach(list => {
          list.name = 'John Doe';
        })
        return listArray;
      })
    )
}

COMPONENT

this._service.getPropertyList()
 .subscribe({
   next: (result) => {
     console.log(result);
   },
   error: (err) => {
     console.log(err);
   }
})

In my component, I am attempting to achieve the desired result like so -

getData(){
   const listData: Array<any> = this._service.getPropertyList();
}

Answer №1

When working with observables, the initial instinct may be to extract the data and store it elsewhere. However, this is often unnecessary. Instead, utilizing pipeable operators can effectively design the behavior and data transformation of emitted values.

Instead of retrieving data in your component using a method:

getData() {
   const listData: Array<any> = this._service.getPropertyList();
}

You could declare the data as an observable that automatically provides the data when available:

data$: Observable<Array<any>> = this._service.getPropertyList();

By taking this approach, your component becomes simpler as it no longer needs to handle fetching the data directly. Instead, it references the observable which will update with any changes to the data.

The $ serves as an indicator that this is a "value that is automatically updated" (observable).

Rather than subscribing in your component as before:

this._service.getPropertyList()
 .subscribe({
   next: (result) => {
     console.log(result);
   },
   error: (err) => {
     console.log(err);
   }
})

You can simplify by defining your data$ as an observable and utilizing Angular's async pipe for subscription handling directly from the template:

data$ = this._service.getPropertyList().pipe(
   tap(result => console.log(result)),
   catchError(err => console.log(err))
});
<ul>
  <li *ngFor="let item of data$ | async">{{ item.name }}</li>
</ul>

Key Operators Used:

  • tap - Executes side effect logic without changing emitted values
  • catchError - Handles errors within the observable stream

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Setting up data in Firebase can be challenging due to its complex structure definition

https://i.stack.imgur.com/iclx7.png UPDATE: In my firebase structure, I have made edits to the users collection by adding a special list called ListaFavorite. This list will contain all the favorite items that users add during their session. The issue I a ...

Error message appears when trying to render a shallow mock of a React.Component that extends MyInterface with any type

Encountering an Issue with Component Mocking When attempting to mock a component, I am receiving the following error message: "Conversion of type '{ props: { index: number; AssignmentTitle: string; AssignmentDescription: string; AssignmentUtilizedHou ...

Implementing atomic design principles in Vue 3 with TypeScript

I'm currently implementing atomic design principles in my Vue application. Here is the code for my button atom: <template> <ElButton :type="button?.type" :plain="button?.plain" :rounded="button?.rounded ...

Establishing reducers within Ngrx

I'm currently in the process of setting up a basic Ngrx state management system. # app.module StoreModule.forRoot(reducers), This particular code snippet has been automatically generated using the Ngrx schematics generators. export const reducers: Ac ...

Server.js experiencing issues with body-parser causing backend to fail loading in browser

Having an issue with my backend server not loading in the browser. It runs fine in terminal, but I can't seem to figure out why it's not working in the browser. I'm new to backend programming and I recently added an app.post method which see ...

Retrieve the encrypted URL

I'm facing an issue with extracting parameters from an encrypted URL. When using the queryparams function, it only retrieves a portion of the URL after being decrypted. For instance, consider this example URL: http://localhost:4200/househouse? MGRjYjQ ...

Angular: handling HTTP errors gracefully in the chain of operations

I am facing an issue where I need to treat specific HTTP error codes as non-errors and handle their responses normally. To achieve this, I implemented an HttpInterceptor to catch 500 status codes and return the original response that Angular stores in erro ...

Eliminating Body Tag Margin in Angular 4: A Step-by-Step Guide

In the Angular 4 project, the app.component.html file does not include a body tag that can be styled to eliminate the padding associated with the body tag. An attempt was made in the app.component.css file to remove the margin with the following code, but ...

Declare, condition, and output all in a single statement

Is there a method to condense the content inside the function below into a single line? I want to avoid declaring check. function Example { const check = this.readByUuidCheck(props) if (check) return this.readByUuid(check) } I am seeking ways to ...

Determining function return property type in Typescript by mapping interface argument property

In order to manage messaging between the browser and a web worker, I have developed a generic class. Each side creates a class that can send specific messages and acknowledge them on the other side with a returned result in a payload. The implementation is ...

Implementing NestJS: Integrating TypeORM Datasource without relying on class dependency injection

I have a unique situation that requires some help. Our team is in the process of integrating nestjs into our current express codebase. Previously, we were using Typeorm 0.2 and recently upgraded to 0.3. Due to the fact that we utilize functions instead of ...

Angular 5 ngIfElse: How to save the outcome of a condition in a storage container

Code Snippet: <mat-icon [ngClass]='{ rotate: !users }'>refresh</mat-icon> <div *ngIf="usersObservable | async as users; else loading"> ... </div> <ng-template #loading let-users> Waiting... </ng-template> ...

Stop allowing the entry of zero after a minus sign

One of the features on our platform allows users to input a number that will be automatically converted to have a negative sign. However, we want to ensure that users are unable to manually add a negative sign themselves. We need to find a solution to pre ...

Angular 7 is throwing an error message stating that it is unable to locate the module named './auth.service'

Currently, I am facing a challenge while using Angular Guards to secure my pages from unauthorized access. import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot , Router } from '@angular/router'; import { Observable } from 'rxjs& ...

Issue with the integration of Angular and Java Jersey API arises when attempting to encode utf-8 whitespaces at the end, resulting in invalid JSON

I'm facing an issue with Angular while making an HTTP GET request. It throws a "Http failure during parsing" error because the JSON response contains whitespace characters at the end. I find it puzzling why the server is returning them. Is there a wa ...

An issue with the validation service has been identified, specifically concerning the default value of null in

Using Angular 10 and Password Validator Service static password(control: AbstractControl) { // {6,100} - Check if password is between 6 and 100 characters // (?=.*[0-9]) - Ensure at least one number is present in the strin ...

Exploring the narrowing capabilities of TypeScript within while loops

When I write while loops, there are times when I know for sure that a certain value exists (connection in this case), but the control flow analysis is unable to narrow it down. Here's an illustration: removeVertex(vertex: string) { const c ...

Angular 2: Enhancing User Experience with Pop-up Dialogs

Looking to implement a popup dialog that requests user input and returns the value. The popup component is included in the root component, positioned above the app's router outlet. Within the popup component, there is an open() method that toggles a ...

Changing the value of an object in Angular can be achieved by utilizing the two

I have a service with the following methods: getLastStatus(id): Observable<string> { let url_detail = this.apiurl + `/${id}`; return this.http.get<any>(url_detail, this.httpOptions).pipe( map(data => { ...

The type 'string' does not share any properties with the type 'CSSProperties'

How can I resolve the issue of Type 'string' has no properties in common with type 'CSSProperties'? const points = 100; const radius = 257; const max = 100; const peaks = [ 10, 50, 90 ]; const step = ...