The inner map function isn't being executed in Rxjs

I have written some code that utilizes two pipes to load a product instance along with its playlist. In case there is an error while loading the playlist, the property is set to null:

getProduct(productId: number): Observable<ProductDTO> {
    return this.internalFindOne(productId).pipe(
      flatMap((productDTO: ProductDTO) => {
        return this.productPlaylistService.getProductPlaylist(productId).pipe(
          map((productPlaylistDTO: ProductPlaylistDTO) => {
            productDTO.playlist = productPlaylistDTO;
            return productDTO;
          }),
          catchError(() => {
            // If product playlist doesn't find anything, we still have to return the product dto object
            productDTO.playlist = null;
            return of(productDTO);
          }),
        );
      })
    );
}

As it currently stands, everything works fine. However, I am unsure about using flatMap in this context. While there are no compiler errors, based on my understanding, flatMap operates in a 1:n manner, whereas map does so in a 1:1 fashion. The code expects a productDTO as input and returns the modified productDTO. When I replace the flatMap with just map, the nested map function isn't called (neither the success nor error parts).

The classes ProductDTO and ProductPlaylistDTOare not iterable.

Could someone help me understand what I might be missing here?

Answer №1

The flatMap operator has a 'flat' prefix because it flattens the observable it returns. This means that instead of getting the observable itself, you will receive the data from the returned observable. It essentially removes one level of nested observables. Its functionality is quite similar to switchMap. For more information on the differences between them, check this post.

In contrast, map solely transforms the data. If you return an observable from the `map()` function, you will get that observable as the result:

internalFindOne(productId).pipe(
  flatMap(() => {
    return getProductPlaylist(productId);
  }),
  tap((additionalData: ProductPlaylistDTO) => { ... })
);

internalFindOne(productId).pipe(
  map(() => {
    return getProductPlaylist(productId);
  }),
  tap((additionalData$: Observable<ProductPlaylistDTO>) => { ... })
);

However, in this scenario where the two requests are independent of each other, you can execute them concurrently using combineLatest:

getProduct(productId: number): Observable<ProductDTO> {
  return combineLatest([
    this.internalFindOne(productId),
    this.productPlaylistService.productPlaylistService(productId).pipe(
      catchError(() => {
        return of(null);
      })
    ),
  ]).pipe(
    map(([ product, playlist ]) => {
      product.playlist = playlist;
      return product;
    })
  );
}

Check out this StackBlitz

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

What is the best way to merge the results of several runs of an observable function

When working with Firestore, I need to retrieve multiple documents, each with a unique sourceAddressValue. This means for a list of N strings, I may need to fetch N documents. I attempted the following approach: getLocationAddresses(addresses: string[]) { ...

unanticipated installation issue with published npm package on verdaccio

I am on a mission to create and release a package containing commonly used TypeScript functions on Verdaccio, an npm registry that operates on Docker. After completing the build for my TypeScript package, this is how my project structure looks: https://i ...

Receiving undefined when subscribing data to an observable in Angular

Currently, I am facing an issue in my Angular project where subscribing the data to an observable is returning undefined. I have a service method in place that retrieves data from an HTTP request. public fetchData(): Observable<Data[]> { const url = ...

Using Cypress and JWT, automate the login process for JHipster

Is there a way to automate the bypassing of the JHipster login screen? This is my goal: let jwt_token before(function fetchUser() { cy.request('POST', '/api/authenticate', { username: 'user', password: &a ...

Utilizing TypeScript in conjunction with Vue and the property decorator to assign default values to props

Hey there! I'm currently dealing with a property that looks like this, but encountering a type error when trying to translate text using i18n @Prop({ default: function() { return [ { > text: this.$t('wawi_id'), align: ...

Form validation is an essential feature of the Angular2 template-driven sub form component

I'm currently working on a template-driven form that includes a group of inputs generated through an ngFor. My goal is to separate this repeating 'sub-group' into its own child component. However, I'm encountering difficulties in ensur ...

Creating React Context Providers with Value props using Typescript

I'd prefer to sidestep the challenge of nesting numerous providers around my app component, leading to a hierarchy of provider components that resembles a sideways mountain. I aim to utilize composition for combining those providers. Typically, my pro ...

Return the subclass from the constructor function

class X{ constructor(input: string) { // do things } f() {console.log("X")} } class Y extends X{ constructor(input: string) { // do things } f() {console.log("Y")} } class Z extends X{ con ...

After subscribing, my Angular template fails to refresh

Currently, I am facing an issue with my Angular 17 project where the data fetched from the API is not updating the template. This means that despite receiving the data, I am unable to display it on the page. The code snippet below shows the service compon ...

Creating a TypeScript mixin with a partial class is a useful technique that allows you to

I am attempting to have class A inherit properties from class B without using the extends keyword. To achieve this, I am utilizing a mixin in the following manner: class A{ someProp: String someMethod(){} } class B implements classA{ someProp: String ...

Unable to retrieve this information within an anonymous function

I am currently working on converting the JSON data received from an API interface into separate arrays containing specific objects. The object type is specified as a variable in the interface. Here is the interface structure: export interface Interface{ ...

Unleashing the power of storytelling with React: A guide to creating dynamic story

weather.stories.ts export default { title: 'Widgets/Forecast', component: Weather, } const Template: Story<any> = (args) => <Weather {...args} />; export const Default = Template.bind({}); Default.args = { forecast: { ...

How can I specify the parameter type as "any object value" in TypeScript?

What is the proper way to annotate a parameter type as "any value of an object"? class ExampleClass { private static readonly MODES = { DEVELOPMENT: 0, PRODUCTION: 1, TEST: 2 } // Any Value of ExampleClass.MODES c ...

Utilizing Database values in .css files with Vue.js and TypeScript

I am currently working on extracting a color value from the database and applying it to my external .css files. I have searched extensively online but haven't found a satisfactory solution yet. Here is the JavaScript code snippet: createBackgroundHead ...

Using TypeScript to create a generic function that returns a null value

In my Typescript code, I have the following function: In C#, you can use default(T), but I'm not sure what the equivalent is in Typescript. public Base { ... } public Get<T extends Base>(cultura: string): T[] { let res = null; try ...

Does anyone have experience using the useRef hook in React?

Can someone help me with this recurring issue: "Property 'value' does not exist on type 'never'" interface InputProps { name: string; icon?: ReactElement; placeholder?: string; } const Input = ({ name, icon: Icon, ...rest }: Inpu ...

Creating TypeScript modules for npm

I have been working on creating my first npm module. In the past, when I used TypeScript, I encountered a challenge where many modules lacked definition files. This led me to the decision of developing my module in TypeScript. However, I am struggling to ...

Undefined value is returned for Vue 3 object property

Is there a way to extract additional attributes from the Keycloak object ? Currently, If I try, console.log(keycloak) it will display the entire keycloak object. Even after reloading, it remains in the console. However, when I do, console.log(keycloak.t ...

What are the TypeScript type definitions for the "package.json" configuration file?

What is the most efficient method for typing the content of the "package.json" file in TypeScript? import { promises as fs } from 'fs'; export function loadManifest(): Promise<any> { const manifestPath = `${PROJECT_DIR}/package.json`; ...

Angular 7 compile error NG8002: Unable to bind object as it is not recognized as a valid property

Currently working on an Angular 7/8 test App. Encountering a compile error Can't bind 'discounter' since it isn't a known property of 'paDiscountEditor' The HTML where the error is occurring is simple... Below are all the nec ...