2
votes

I am trying to iterate on an Observable of the RxJS store state by using:

ngOnInit() {
this.route.params
  .subscribe(
    (params: Params) => {
      this.index = +params['propertyId'];
      this.propertyState = this.store.select('propertyState');

      if (Number.isInteger(this.index)) {
        this.store.dispatch(new fromPropertyAction.SelectProperty(this.index));
      }
    }
  );

}

HTML: *ngFor="let property of (propertyState | async).properties; let i = index" (click)="onSelectProperty(i)"

And also tried:

ngOnInit() {
this.route.params
  .subscribe(
    (params: Params) => {
      this.index = +params['propertyId'];
      this.store.select('propertyState').subscribe(data => {
        this.properties = data.properties;
      })

      if (Number.isInteger(this.index)) {
        this.store.dispatch(new fromPropertyAction.SelectProperty(this.index));
      }
    }
  );

}

HTML: *ngFor="let property of properties; let i = index"

But both cases I get this error.

Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

Also, store here is declared in the constructor of type: private store: Store

fromApp.AppState is in the app reducer:

export interface AppState {
    propertyState: fromPropertyReducer.State
}

fromPropertyReducer.State is in the property reducer:

export interface State {
    properties: Property[];
    selectedProperty: Property;
    selectedPropertyIndex: number;
    openAllProperties: boolean;
    selectedPropertyExpenseIndex: number;
}

Also, initially the properties shows up fine in the html iterating over the array. But after an action to add a new expense to the property.expenses array, does this error occur. This is how I am adding the new expense in the reducer:

case PropertyListActions.ADD_PROPERTY_EXPENSE:
        let property = state.properties[state.selectedPropertyIndex];

        const updatedExpenses = [
            ...property.expenses,
            action.payload
        ];

        const updatedProperty = {
            ...property,
            expenses: updatedExpenses
        };

        const updatedProperties = {
            ...state.properties,  
        };

        updatedProperties[state.selectedPropertyIndex] = updatedProperty;

        return {
            ...state,
            properties: updatedProperties    
        }

I looked at others' post so tried the second method but didn't work. Please help. Thank you.

1
try this --> this.propertyState = this.store.select('propertyState').map(data => { this.data = data; return data.properties }) - Praveen Soni
how data look like. - Praveen Soni
Your action "SelectProperty" would lead us to believe the data being returned is a single object of type Property and not an Array of objects of Property (i.e. Properties: Property[]). Please post the class showing the data you expect back from the action/effect. Thanks. - Adam Cox
Please post the class showing the data you expect back from selector (i.e. propertyState). Thanks. - Adam Cox
Please see my updates above for the store and propertyState type is. I tried the first suggestion but there is no map attribute. Thank you for your help! - Evan

1 Answers

0
votes

Thank you everyone for your help! I just figured it out following the thinking that you have suggested that my propertyState.properties needs to be an array. Since the error happened after an action is issued, I found the error to be in the reducer. updatedProperties should be an array and I had it as an object before. Thanks again for your help! I greatly appreciate it.