Q:

Redux - cross-entity state management

I'm using Redux and ImmutableJS to manage the state of my app. I've created the following two Records:
export const OrderRecord = Record({
    id: null,
    productId: null,
    amount: 1,
});

export const ProductRecord = Record({
    id: null,
    name: '',
    price: 0,
});

My global state is normalized based on the normalizr approach like this:
const state = {
    entities: {
        orders: new OrderedMap(new Map({
            1: new OrderRecord(createOrderItem(1, 1)),
        })),
        products: new OrderedMap(new Map({
            1: new ProductRecord(createProductItem(1)),
        })),
    },
};

I'm using this specification for testing purposes. 

Now I'm trying to make some selects with computed fields using Reselect.
export const getVisibleOrders = createSelector(
    [getProducts, getOrders],
    (products, orders) => {
        orders.map(order => {
            const product = products.get(order.productId.toString());
            if (!product) {
                return order;
            }
            const totalPrice = order.amount * product.price;
            order.set('productName', product.name);
            order.set('totalPrice', totalPrice);
            return order;
        });
    }
); 

, but I get the following error message:

Error: Cannot set unknown key "productName" on Record

I know the reason - Record cannot contain any undefined keys, but my question is: Is there any suggested approach how gracefully solved this problem? 

I don't want to extend my Records to support this kind of computed parameters (product.name and totalPrice). 
I don't want to keep the static and computed parameters in one place, because for example the 'productName' parametr is from "Product" entity and not from "Order" entity.

Thank you.

A:

The whole point of using Immutable.Record is to not let you add new keys to your record, hence the error message you get. And the whole point of selectors is to expose such "computed" property if you want to consume them outside. In your case, you can simply return a new Map() object or a new record type if you need to use the dotted syntax :
return Map({
  productName: 'foobar'
}).merge(order)

