An effective way to retrieve a property from an observable by utilizing a pipe

I'm having trouble storing an OrderState object in my ngrx store and extracting data from it for my UI using the async pipe. Specifically, I want to retrieve a child property from this observable object.

order.state.ts

export interface OrderState {
    stage: number;
    postcode: string;
}

app.component.ts

...
export class AppComponent {
  counter: Observable<number>;
  readonly orderState$: Observable<OrderState>;

    constructor(
      private appStateStore: Store<AppState>,
      private counterActions: CounterActions,

      private orderStateStore: Store<OrderState>,
      private orderActions: OrderActions,
    ) {

    this.counter = appStateStore.select('counter');
    this.orderState$ = orderStateStore.select(store => store);
    }
...

app.component.html

<div>Stage: {{ (orderState$ | async)?.stage }}</div>

What is the syntax needed to access the stage property from my orderstate object?

When I display {{ orderState$ }}, I only see [Object object]. Am I not selecting from my store correctly?


Update: There seems to be a basic issue here. I tried this to understand what's happening...

app.component.ts

stage: number

...

    this.orderStateStore.select(s => s).subscribe((data:OrderState) => {
      this.stage = data.stage;
      console.log(this.stage);
    });

app.component.html

<div>Stage: {{ stage }}</div>

In the console, I can see that stage reports as undefined. This might be contributing to the problem. It seems like I cannot set the stage of my component inside this arrow function.


Update: The behavior is quite perplexing...

order.state.ts

export interface OrderState {
    stage: number;
    postcode: string;
}

app.component.ts

...
this.orderStateStore.select(s => s).subscribe((data:OrderState) => {      
  console.log('--- START ---');
  console.log(data);
  console.log('Stage: ' + data.stage);
  console.log('--- END ---');
});
...

Here's what I observe in the console...

https://i.stack.imgur.com/jzxU6.png

It appears that data isn't actually of type OrderState. Instead, it is the wrapper type around OrderState called AppState. Although I attempt to log data.orderState.stage to obtain the value 1, TypeScript throws an error stating that orderState is not a property of data - even though it clearly is based on the console output!

Answer №1

When utilizing {{ orderState$ }}, you may notice it displays [Object object] because it converts the async pipe result (an object) to a string. To extract a specific property using a pipe, consider this approach:

{{orderState$ | async | asyncField : 'stage'}}

The custom pipe code would resemble:

@Pipe({name: 'asyncField'})
 export class AsyncFieldPipe implements PipeTransform {
     transform(object, key: string){
        return object[key];
     }
 }

This setup passes the async pipe result to the created pipe and retrieves a designated field. For reference, a functional plunkr can be found here.


Update: An alternative to using a pipe involves employing the rjxs map method to filter what is returned from the observable sequence. This method offers more flexibility for accessing response properties, potentially requiring a more intricate transformation function in the component.ts file.

this.orderState$ = orderStateStore.select(store => store).map(res => res.stage);   

For a demonstration, refer to this functioning plunkr here.

Answer №2

Follow these steps to extract the current stage from the asynchronous order state: {{(orderState$ | async).stage}}

Answer №3

It appears that my initial selection from the ngrx store was incorrect.

MISTAKE

this.orderState$ = orderStateStore.select(store => store);

CORRECTED

this.orderState$ = appStateStore.select(x => x.orderState);

In hindsight, it is clear that I should have accessed the orderState directly within the appStateStore. The structure of my store objects is as follows:

app.state.ts

export interface AppState {
  counter: number;

  orderState : OrderState;
}

order.state.ts

export interface OrderState {
    stage: number;
    postcode: string;
}

OrderState is a subset of AppState. Therefore, I needed to access the orderState property using the => function when querying the appStateStore.

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

When using the Angular Material table with selection enabled, the master toggle functionality should always deselect the

I made modifications to the original Angular Material Table example - Stackblitz. In my version, when some rows are selected and the master toggle is clicked, all selected rows should be deselected (similar to Gmail behavior). The functionality works, but ...

Angular 2, 4, or 5 - the powerful choices for web

As I make the shift from AngularJS to Angular, I am seeking advice from fellow developers on which version of Angular to focus on learning. I have been utilizing AngularJS 1.3.7, but realize that it is outdated with significant advancements in Angular 2 a ...

Using a dictionary of class types as input and returning a dictionary of their corresponding instances

Is there a way to create a function that takes a dictionary with class values as an argument and returns a dictionary of their instances? For example: classes C1, C2 function f: ({ name1: C1, name2: C2 }): ({ name1: new C1() name2: new C2 ...

What is the best way to transmit a JSON object to REST services using Angular?

Whenever I attempt to send the JSON object to REST services, I encounter an error that looks like this: http://localhost:8080/api/v1/cardLimit 400 (Bad Request); JSON Object Example: public class GameLimit implements Serializable { private stati ...

The command "tsc" was not found in this bash session

Currently, I am using a MAC and attempting to set up TypeScript. I followed the installation process by running sudo npm install -g typescript and received the following output: Password: /Users/<myuserid>/node/bin/tsc -> /Users/<myuserid& ...

The issue of TypeError arising while invoking a method within TypeScript Class Inheritance

Currently, I am developing a Node.js application with TypeScript. In this project, I have a base controller class named BaseController and a derived controller called SettingController. The intention is for the SettingController to utilize methods from the ...

Dropdown within Datatable does not automatically select the bound option [PrimeNG]

Hey there! I'm a trainee just entering the world of frontend development, so apologies in advance if my question seems silly or if my code looks messy (any corrections are greatly appreciated). In my project, I have a Dropdown element inside a Datata ...

Develop a Nativescript Angular component dynamically

Is there a way for me to dynamically generate a Component and retrieve a View object to insert into a StackLayout? ...

Tips on updating primeng Panel Menu appearance with scss

I'm looking to customize the color of my panel menu to black. Below is the HTML code I am using. <p-panelMenu styleClass="font-bold text-xs m-0 w-11" [model]="items" [multiple]='false'></p-panelMenu> ...

ngModelChange not triggered when updating the model from a component

I am currently exploring Angular and trying to grasp the concept of connecting different controllers to update their values based on changes in one controller. In a specific scenario, I have a form with ngModel and I am attempting to utilize ngModelChange ...

Refreshing MongoDB data by utilizing values from an object

I am facing a challenge with my MongoDB collection structure: [ { "stock": "GOOGLE", "price": 0 }, { "stock": "FACEBOOK", "price": 0 } ] On the other hand, I have a Stock_P ...

Can you explain the significance behind the syntax used in ngrx adapter selectors?

Stumbled upon this ngrx adapter example: export const { selectAll: selectAllItems } = adapter.getSelectors<State>(state => state.items); Confused about the assignment in this code snippet. Specifically, the notation involving a type: const ...

Why does Typescript not enforce a specific return type for my function?

In my custom Factory function, I need to return a specific type: type Factory<T> = () => T; interface Widget { creationTime: number; } const createWidget: Factory<Widget> = () => { return { creationTime: Date.now(), foo: &a ...

Solidjs: Implementing a Map in createStore does not trigger updates upon changes

As a beginner in solidjs, I might have missed something important. In the code snippet below, I am trying to understand an issue: const [state, setState] = createStore({ items: new Map() }); // e.g. Map<number, string> In a component, suppose I want ...

Retrieve information from Angular 2 response

In my code, I am working with 1 component and 1 service. Here is the component element : ... constructor(private requestService : RequestService) { } ngOnInit() { this.a = this.requestService.send_request(urlWebAPI); console.log(this.a); } ... ...

Angular 4 is unable to attach to 'formGroup' as it is not recognized as a valid property of 'form'

As a beginner with Angular 4, I decided to explore model driven forms in Angular 4. However, I keep encountering this frustrating error. Template parse errors: Can't bind to 'formGroup' since it isn't a known property of 'form ...

Employing the Eclipse Palantir TypeScript Plug-in in conjunction with JSPM

I currently utilize the Palantir Eclipse TypeScript Plug-in (v1.8.0.v20160223-1645), which functions flawlessly when my d.ts files are stored in the same source folder /src. However, due to JSPM, these files reside in a different folder now, causing issues ...

Disallow the use of properties in a nested interface

Is there a way to define an interface or type that restricts a specific key in a child of the interface when used in union types? I am looking for the correct definition for Abc: type Abc = { someField: { prohibited?: never, }, }; type Use ...

Is it possible to use Angular signals instead of rxJS operators to handle API calls and responses effectively?

Is it feasible to substitute pipe, map, and observable from rxjs operators with Angular signals while efficiently managing API calls and their responses as needed? I attempted to manage API call responses using signals but did not receive quick response t ...

Using the original type's keys to index a mapped type

I am currently developing a function that is responsible for parsing a CSV file and returning an array of objects with specified types. Here is a snippet of the code: type KeyToTransformerLookup<T> = { [K in keyof T as T[K] extends string ? never : ...