I want to create a new property in an array by using the value of a property in an observable object, and then applying a function that returns an observable

Within my code, there exists an observable array filled with objects:

 let people = of([
    { firstName: 'John', lastName: 'Doe' },
    { firstName: 'Jane', lastName: 'Doe' },
    { firstName: 'John', lastName: 'Smith' },
    { firstName: 'Jane', lastName: 'Smith' },
  ])

In addition, a function is present that leverages two properties from the objects to generate an observable:

 function fullName(firstName: string, lastName: string) {
    return of(`${firstName} ${lastName}`)
  }

The challenge I am facing involves combining these two elements to produce the desired output:

fullNamePeople: Observable<{
    firstName: string;
    lastName: string;
    fullName: string;
}[]>

To exhibit the final observable in an Angular context using the async pipe, variations of operators have been experimented with. However, the outcomes differ from initial expectations.

An attempt utilizing concatMap yields:

fullNamePeople: Observable<{
    fullName: Observable<string>;
    firstName: string;
    lastName: string;
}>

It was anticipated that concatMap's functionality aligns with the objective, but this does not appear to be the case.

Switching to map results in an array yet still incorporates a nested observable:

fullNamePeople: Observable<{
    fullName: Observable<string>;
    firstName: string;
    lastName: string;
}[]>

A solution achieved through the following implementation:

fullNamePeople = this.people.pipe(
    mergeMap(people => people.map(person => this.fullName(person.firstName, person.lastName).pipe(
      map(fullName => ({...person, fullName}))
    ))),
    mergeAll(),
    toArray()
  );

Despite its success, concerns arise regarding efficiency and optimization of this approach.

Answer №1

Finding a solution for your specific requirement may not be straightforward.

After much consideration, the approach I settled on is outlined below:

individuals
  .pipe(
    // Begin by waiting for the initial Observable to notify the array
    // Once the notification is received, switch to a new Observable using switchMap
    switchMap((array) =>
      // Transition to an Observable that streams the values of the array
      // Using the rxjs from function
      from(array)
    ),
    // Transform each value of the array into an Observable with the fullName function
// Then merge the values of this stream of Observables using mergeMap
mergeMap((data) =>
fullName(data.firstName, data.lastName).pipe(
map((fullName) => ({ ...data, fullName }))
)
),
// Finally, use toArray to consolidate the values into a single array
// Notified when the upstream completes
toArray()
)

You can view a live example on StackBlitz showcasing this code snippet.

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

methods for transforming JSON array output objects into individual non-array values

I'm facing an issue with a JSON result that contains latitude and longitude as an array like [13.0801721, 80.2838331]. I need help in converting this to comma-separated values without the array brackets, similar to 13.0801721, 80.2838331. This is my ...

I don't understand why I always need to refresh the page after deleting a row

Currently, I am working on implementing the delete row functionality for my table which is populated with data from an API. The delete request is functioning properly, however, I am facing an issue where I have to manually refresh the page in order to se ...

What is the best way to interact with the Document Object Model using Angular

Currently in my work with Umbraco (cms) and Angular, I find myself needing to access a DOM property of umbraco. The current solution involves using jQuery for this purpose, but I am looking to eliminate all jQuery dependencies from the codebase. Is there ...

Modifying the value of an object key with Javascript

The information I am working with is structured as follows: obj = { pref: { language: 'English', } }; My goal is to update the language field to 'Spanish'. ...

Implement dynamic validation in Angular 4 based on specific conditions

I am looking to implement Angular 4 validation dynamically based on specific conditions within a Reactive form. Here is the scenario: There is a radio button with options: A: yes B: no If the user selects "yes", a textbox (formControlName="your_name") wil ...

How can we prevent Material-UI and Redux-form from re-rendering when an option is clicked in the select input?

I am facing an issue with rendering options dynamically. Whenever I click on the select or the options, the component re-renders and changes the options. As a result, I need to click twice to select an option in the dropdown. This re-rendering is happening ...

Stop the timer on a photo carousel when clicking on an image

After creating a photo slider and implementing some w3 CSS to display a photo modal upon clicking an image in the slider, I encountered an issue. When the JavaScript code tries to slide the slider, it disrupts the modal if it is open. Is there a way to pau ...

Develop a Vue component for a fixed sidebar navigation

I am in need of a vertical navigation bar positioned to the left of my app's layout, with the content extending across the right side. However, I am currently facing an issue where the navbar is pushing all the content downwards. How can I resolve thi ...

transform a JSON object into a hierarchical JSON tree object

Take a look at my code here, but read this first. I am attempting to transform tab-indented text into a tree structure. Despite searching for similar issues, I have not found a satisfactory solution yet. Once I resolve this problem, I will share the comple ...

Prevent redundancy by caching svg icons to minimize repeated requests

I have a collection of info cards on my page, each featuring its own unique illustration along with a set of common icons (SVG) for options such as edit, delete, and more. While the illustrations vary from card to card, the icons remain consistent across a ...

Zurb Foundation's sections have a strange issue where navigating between them introduces unexpected whitespace

I'm feeling frustrated as I try to work with Zurb Foundation sections. I've updated to the latest version 4.3.1. Following the documentation provided here: but encountering strange behavior while navigating through results. Refer to the screen ...

Guide on how to add multiple options to a select element in HTML using prototype.js

What is the best way to add multiple options to a select tag in HTML using prototype js? Appreciate your help. ...

Optimizing performance: Enhance readback operations in Canvas2D by enabling the willReadFrequently attribute for faster getImageData processing

I am currently utilizing the react-wordcloud package and encountering an issue where the word cloud adjusts to fit 70% of the screen size whenever the container size changes. My console is being flooded with this warning message: https://i.sstatic.net/vdV ...

Don't forget to add a line break whenever you're using $().html with jQuery

I've been attempting to input this information into a text area with the ID "registers," but no matter what I try, I can't seem to create a new line within the text area. var r0=0,r1=0,r2=0,r3=10; $('#run').click(function(){ ...

Tips for updating button appearance when clicked using React Bootstrap

Is there a way to add custom styling to a toggle button in React? I want the button to change color when selected, but the issue is that the color reverts back to default once the click is released. Can anyone assist me with this? Below is my React Compon ...

Tips for resolving the error message "Cannot use type '{}' as an index type"

interface TicketTime { startTime: string; endTime: string; } interface TicketInfo { id: number; from: string; to: string; company: string; price: number; time: TicketTime; duration: number; connectionAmount: numb ...

Transmit information from the backend Node.js to the frontend (without using sockets)

Is there a method to transfer data from my socket, for example example.com:8000, to my web server that is not on the same socket at example.com/index.php? I've searched through various codes but have not come across any solutions yet. If you could pro ...

Issue with Angular Material table: unable to bind to 'matRowDefColumn'

I am attempting to utilize an Angular Material table. I have imported the module, but I am encountering a template parse error. HTML: <mat-table [dataSource]="dataSource"> <ng-container matColumnDef="name"> <mat-header-cell *matHeade ...

Is it possible to utilize a template literal with a variable as an object key?

I tried to run the following code snippet but encountered an unexpected error: interface Person { firstName: string } const property: 'Name' = 'Name' const zack: Person = { [`first${property}`]: 'Zack' } An error is th ...

What are the best methods for creating JavaScript charts that efficiently handle massive amounts of data?

After conducting a thorough search, I couldn't find any article similar to what I'm working on for my ASP.Net MVC4 project. The main challenge we're facing is drawing charts with AJAX and JavaScript for extremely large amounts of data. For ...